将servlet作为OSGI组件引用是一种好习惯吗?

时间:2017-01-20 15:51:16

标签: osgi cq5 aem

在我的项目中,我们有几个servlet是osgi组件,并且具有绑定它们的属性。喜欢

@Component(label = "Default Address Servlet", immediate = true)
@Service(value = Servlet.class)
@Properties(
    @Property(name = "sling.servlet.resourceTypes", value = { "sling/servlet/default" }),
    @Property(name = "sling.servlet.selectors", value = { "defaultaddress" }),
    @Property(name = "sling.servlet.extensions", value = { "json" }),
    @Property(name = "sling.servlet.methods", value = { "POST" }), 
    @Property(name = "prop1", value = { "value1" }) })
public class SetDefaultAddressServlet extends SlingAllMethodsServlet {

现在我需要在加载组件期间在吊索模型类中使用此prop1。虽然技术上servlet是osgi组件,但可以将这个servlet作为osgi组件引用吗?喜欢

@Model(adaptables = SlingHttpServletRequest.class)
public class Address {

    @Inject
    @Reference
    private SetDefaultAddressServlet service;

虽然这在技术上是正确的,但这是一个好方法吗?或者,我需要使用相应的属性创建单独的OSGi服务并引用它。什么是可行的方法?

2 个答案:

答案 0 :(得分:1)

这是一个哲学问题,而不是技术问题,因为没有人可以给你100%正确答案,但我会在那里表达我的意见。

我更喜欢将六边形体系结构应用于我的代码(original post on this patternanother great one),这会为您的应用程序带来高可维护性。

其主要思想之一是依赖关系应该指向内部 - 所以外部世界依赖于你的servlet,servlet依赖于你的业务层。

这里可以将Servlet视为外部世界和业务逻辑之间的适配器。 Sling Model是一样的 - 它位于你的html页面和服务之间。

根据这种设计模式,从另一个适配器引用一个适配器是个坏主意。

此外,还有一个灯code smell:这些类需要这个属性的用途是什么?应该将需要相同属性的代码放在两个不同的位置,而不是放在一个小的Util类或服务中吗?

同样,这只是我的意见。

答案 1 :(得分:1)

只是为了添加其他用户的上一个答案,并且鉴于它不是一个可靠的代码架构方法,在AEM环境中,这也不是一个好方法。

您的模型(地址)取决于服务实施。 servlet中有很多与HTTP请求相关的信息,通常这个模型不需要访问HTTP servlet中的所有重信息。

您可能希望访问HTTP请求中的一些有限属性集,并将它们转换为POJO模型,这些属性可以是请求信息的一部分。在这种情况下,最好从HttpRequest或一些可以从您的请求中提取的更多以价值为中心的对象制作适应性。

另外,请考虑其他用户指出的代码异味。什么阻止Address对象调用引用类上的Servlet方法并修改请求的状态(如访问会话等)。

同样,它有效,但它不是最佳方式,因为只有通过将其限制为AEM最佳实践才有更好的方法。我建议您阅读以下文章:

https://sling.apache.org/documentation/bundles/models.html

希望这有帮助

相关问题