【问题标题】:Spring: init-method, PostConstruct, afterPropertiesSet : when to use one over others?Spring:init-method、PostConstruct、afterPropertiesSet:何时使用其中一个?
【发布时间】:2014-10-21 03:12:40
【问题描述】:

spring bean 生命周期中有很多可用的初始化选项。

init-methodPostConstruct注解、afterPropertiesSet、Bean post-initialization甚至类构造函数。所有这些都可以用于初始化一个bean。

我很困惑何时使用这些而不是其他。此外,是否有任何情况下我们可能需要在单个 Bean 中使用所有这些选项?如果是,请举个例子。

真的很期待得到一些很好的答案。

【问题讨论】:

    标签: java spring


    【解决方案1】:

    我个人在 xml 配置中使用 init-method 仅用于模拟/单元测试。在许多情况下,我发现自己需要在 bean 中使用不同的逻辑或不同的属性值(即模拟数据)进行测试。此外,模拟数据通常会根据测试用例而变化。在这些情况下,我发现在一个配置中拥有多个与案例相关的版本会更简洁。这样,它们可以被交换出来,而无需更改类本身的任何内容。这不是依赖注入的主要目的吗?

    通过构造函数初始化 bean 时,您必须将依赖于测试的初始化问题(例如使用模拟值初始化)写入所述构造函数(或者编写多个构造函数)。通过这样做,您将测试逻辑硬编码到您的类中。避免这种做法是创建像 Spring 这样的框架的主要原因之一。

    【讨论】:

    • 如果这听起来仍然令人困惑,我深表歉意。我试图对其进行编辑以减少它。
    【解决方案2】:

    使用构造函数和其他选项的区别在于构造函数代码是最先被执行的,而其他选项只有在依赖注入到bean之后才会被调用(来自@Autowired 注释或 XML 文件)。

    您在构造函数中编写的代码将在 bean 的属性仍未启动时运行。所有 @Autowired 字段都将为 null。有时这是您想要的,但通常您希望代码在设置属性后运行。

    除此之外,我看不出有什么不同,除了执行顺序。我不认为你会希望在同一个类中拥有所有选项。

    【讨论】:

      【解决方案3】:

      我建议您只在可能的情况下使用构造函数。这样做有一个非常好的理由:测试

      当您要对 Spring bean 进行单元测试时,您会希望能够以最少的麻烦构建类。这意味着您应该只需要调用构造函数,而不必自己处理调用各种生命周期方法。创建要测试的类时,您最不想做的就是必须知道对象的属性是如何初始化的。

      借助 Spring 的构造函数注入支持,您可以轻松地将其他其他 bean 或项目属性注入到构造函数中,从而能够覆盖几乎所有场景。

      【讨论】:

      • 几乎所有场景,除了不能使用构造函数注入的情况(即循环依赖)。在这种情况下,您可以初始化 bean 的唯一方法是 @PostConstruct 及其替代方法。
      • 我认为这个 [good] 答案暗示使用“构造函数注入”,只是为了清楚......如果你确实走这条路,另外有任何 PostConstruct 注释可能是不明智的( stackoverflow.com/a/3406690/1357094) 在同一个班级。如果仍然如此,则不会在 [i.e:] vanilla JUnit 测试中调用 @PostConstruct 方法,因为那里不涉及 Spring!
      猜你喜欢
      • 2019-05-02
      • 2016-02-10
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多