Spring@PostConstruction 与 init-method 属性

使用 @PostConstruct注释和在 Spring XML 配置中声明与 init-method相同的方法有什么区别吗?

113829 次浏览

没有真正的区别。这取决于您喜欢如何配置您的系统,这是一个个人选择的问题。就我个人而言,我更喜欢对自己的代码使用 @PostConstruct注释(因为 bean 只有在调用方法之后才能正确配置) ,并且在从不支持 Spring 的库实例化 bean 时使用 init-method(当然,这里不能应用注释!)但我完全能理解人们想要以这样或那样的方式去做所有的事情。

不,实际上我并不认为这有什么不同,但是他们的工作方式是有优先级的。@PostConstructinit-method是 BeanPostProcessor。

  1. @PostConstruct是 JSR-250注释,而 init-method是 Spring 使用初始化方法的方式。
  2. 如果您有一个 @PostConstruct方法,那么在调用初始化方法之前,将首先调用这个方法。
  3. 如果 bean 实现 InitializingBean 并覆盖 afterPropertiesSet,则首先调用 @PostConstruct,然后调用 afterPropertiesSet,然后调用 init-method

更多信息,您可以检查春天的 参考文件

在 JSR 250规范之前,在 xml 中使用 init-method 是首选的方式,因为它将 java 类(bean)与任何 Spring 特定的类/注释分离开来。因此,如果您正在构建一个不需要依赖于 Spring 基础设施 bean 的库,那么使用 init-method 是首选的方式。在创建方法期间,您可以指定需要作为初始化方法调用的方法。

现在,随着 JavaEE 中 JSR250规范的引入以及对这些注释的 Spring 支持,对 Spring 框架的依赖性已经在一定程度上减少了。

但是我必须承认,增加这些东西可以提高代码的可读性。所以这两种方法都有利有弊。

@postconstruct is not part of the spring. It is part of javax package. Both are the same. using init-method we need to added in xml file.If you use @postconstruct adding in xml is not required. Check out the below article .

Http://answersz.com/spring-postconstruct-and-predestroy/

完整代码: https://github.com/wkaczurba/so8519187(弹簧靴)

使用注释:

@Slf4j
@Component
public class MyComponent implements InitializingBean {


@Value("${mycomponent.value:Magic}")
public String value;


public MyComponent() {
log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
}


@PostConstruct
public void postConstruct() {
log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
}


@Override // init-method; overrides InitializingBean.afterPropertiesSet()
public void afterPropertiesSet() {
log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
}


@PreDestroy
public void preDestroy() {
log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
}
}

Gets us:

刷新 org.springframework.context..。

构造函数中的 MyComponent: [ null ]
MyComponent in postConstruct: [Magic]
属性集中的 MyComponent: [ Magic ]
...

在启动时注册用于 JMX 公开的 bean
用0.561秒启动 DemoApplication (JVM 运行于1.011)
关闭 org.springframework.context... 在关闭时注销暴露 JMX 的 bean

...
毁灭前的我部件: [魔法] < br/>

There 也许吧 difference between @PostConstruct and init-method because @PostConstruct is handled in the postProcessAfterInitialization phase of bean initialization (AbstractAutowireCapableBeanFactory.initializeBean() method) by CommonAnnotationBeanPostProcessor, while init method gets called after the completion of postProcessBeforeInitialization phase (and, for this matter, before the beginning of postProcessAfterInitialization phase).
编辑: 所以,顺序是: 1) postProcessBeforeInitialization phase, 2)调用 init方法, 3) postProcessAfterInitialization phase, which calls @PostConstruct method

(附注: 来自已接受的答案的陈述

@ PostConstruction,init-method 是 BeanPostProcessor

不完全正确: @PostConstructBeanPostProcessor处理,而 init方法则不是。)

如果一些(潜在的自定义) BeanPostProcessor(配置为(Ordered.getOrder())在 CommonAnnotationBeanPostProcessor之后执行)在其 postProcessBeforeInitialization方法中正在执行某些严重的操作,那么 将会是就会有所不同。
不行与默认的 Spring 配置 BeanPostProcessors有任何不同,因为所有配置为在 CommonAnnotationBeanPostProcessor之后执行的 BeanPostProcessorspostProcessBeforeInitialization方法中不执行任何操作。

总之,在99% 的案例中,接受的答案和类似的答案都是正确的,这篇文章只是向“细节决定成败”这一概念致敬

正如您可以在下面的 豆子创造生命周期回调图表中看到的。

Bean Creation Life-Cycle Callback

这三个步骤发生在豆子创造生命周期回调中:

  1. 提到 @PostConstruct将被调用。
  2. 如果实现了 InitializingBean,那么将调用 afterPropertiesSet()
  3. 如果 bean 定义包含 init-method@Bean(initmethod=".."),那么它将调用 init 方法。

This diagram is from Pro Spring 5: Spring 框架及其工具的深入指南