【问题标题】:What is the use of @postconstructor in AEM SlingModel concept?AEM SlingModel 概念中@postconstructor 的用途是什么?
【发布时间】:2018-06-14 02:10:16
【问题描述】:

当我在SlingModel中使用时,我什么时候可以使用@postconstructor

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

    @Inject
    private PrintWriter out;

    @Inject
    @Named("log")
    private Logger logger;

    @PostConstruct
    protected void sayHelloTest() {
        logger.info("hello world");
    }
}

【问题讨论】:

  • 请在此处提问之前阅读文档。 sling.apache.org/documentation/bundles/…
  • @AhmedMusallam,我读了你分享的那个文件。我是 SlingModel 的新手。我没有得到任何明确。你能解释一下吗?
  • @Sara_123 按照这个StackOverflow blog article我回答了你的问题。通常,您应该仔细阅读文档并真正尝试解决您的问题。在 StackOverflow 上问一个简单地跳过谷歌搜索的问题通常是不受欢迎的。反正。希望我的回答能帮助你理解@PostContruct注解的作用。

标签: aem sling-models


【解决方案1】:

documentation 声明:

@PostConstruct 注解可用于添加在所有注入完成时调用的方法:

在您提供的示例代码中,文档谈到的“注入”是您使用 @Inject 注释进行注释的字段。

当 Sling 模型被实例化时,这些字段将被 Sling “注入”。这意味着您不必自己设置这些字段,但 Sling 会处理它。这也称为Dependency Injection

回到你的问题:一旦所有这些字段都被 Sling 注入,带有 @PostConstruct 注释的方法将被调用。通常,开发人员使用此方法对 Sling 模型进行进一步初始化。

整个过程是这样的:

  1. Sling 会为您的模型创建一个新实例(例如 new MyModelTest())。
  2. Sling 会注入您声明的所有依赖项(请参阅@Inject 注释)。
  3. Sling 将调用带有@PostConstruct 注释的方法。

@PostConstruct 注释基本上是构造函数的替代品。如果你要为你的模型写一个构造函数,你会注意到当构造函数被调用时,所有带有@Inject注解的字段都还没有设置。如果您尝试对这些字段进行进一步初始化,您将获得NullPointerException

这就是引入@PostConstruct 注释的原因。它允许您执行通常在构造函数中执行的进一步初始化。

补充说明

将依赖项注入字段称为“字段注入”。还有另一种方法可以通过构造函数注入这些依赖项。这称为“构造函数注入”。

就我个人而言,我喜欢尽可能在 Sling 模型中使用构造函数注入。使用构造函数注入有助于提高模型的不变性,有助于减少状态并提高可测试性。这是您通常应该在代码中努力实现的目标。

您的代码示例将与构造函数注入如下:

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

    private final Logger logger;
    private final PrintWriter out;

    @Inject
    public MyModelTest(
        @ScriptVariable @Named("log") final Logger logger,
        @ScriptVariable @Named("out") final PrintWriter out
    ) {
        this.logger = logger;
        this.out = out;
    }
}

类字段 loggerout 现在可以设置为 final,这增加了不变性,因为它们不能再更改了。

当您注入服务等进行进一步初始化时,您也可以将结果存储在final 类字段中,而不是将服务引用本身作为类字段注入。这些引用——理论上——可能指向一个不存在的服务(服务可以在 OSGi 中来来去去)。例如:如果您有一个存储您需要的配置的服务,您可以读取您感兴趣的配置值,然后将其存储在一个类字段中。

最后但同样重要的是,可测试性得到了改进,因为您现在可以通过简单地调用 new MyModelTest([...]) 并传递 loggerout (new MyModelTest(mockLogger, mockOut)) 的模拟来创建实例。如果您要使用字段注入,则必须使用reflection,这通常不是您想要在代码中执行的操作。虽然不得不说 Sling 项目包含对使用场注入的测试模型的支持。

【讨论】:

  • @Sara_123 如果此答案对您有所帮助,请接受它作为正确答案。如果您对我的回答有任何疑问,也请随时提出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 2012-10-04
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多