Spring @PostConstruct与init-method属性

时间:2011-12-15 11:15:05

标签: spring

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

6 个答案:

答案 0 :(得分:142)

实际上,我并不认为存在任何差异,但工作方式有优先考虑。 @PostConstructinit-method是BeanPostProcessors。

  1. @PostConstruct是JSR-250注释,而init-method是Spring的初始化方法。
  2. 如果您使用@PostConstruct方法,则会在调用初始化方法之前先调用此方法。
  3. 如果您的bean实现了InitializingBean并覆盖afterPropertiesSet,则先调用@PostConstruct,然后调用afterPropertiesSet,然后调用init-method
  4. 有关详细信息,您可以查看Spring reference documentation

    在JSR 250规范之前,在xml中使用init-method是首选方法,因为它将java类(bean)与任何特定于spring的类/注释分离。所以如果你正在构建一个不需要依赖的库spring spring method然后使用init-method是首选。在创建方法中,你可以指定需要作为初始化方法调用的方法。

    现在,随着Java EE中JSR 250规范的引入以及对这些注释的弹性支持,对spring框架的依赖已经在一定程度上得到了降低。

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

答案 1 :(得分:18)

没有真正的区别。这取决于您喜欢如何配置系统,这是个人选择的问题。我自己,我更喜欢为我自己的代码使用@PostConstruct注释(因为bean只在调用方法后才能正确配置),并且在从非Spring感知库实例化bean时使用init-method(可以&当然,在那里应用注释!)但是我完全可以理解想要以这种方式做到这一点的人。

答案 2 :(得分:4)

@postconstruct不是春天的一部分。它是javax包的一部分。两者都是一样的。使用init-method我们需要在xml文件中添加。如果使用@postconstruct,则不需要在xml中添加。请查看以下文章。

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

答案 3 :(得分:2)

如下面的 Bean创建生命周期回调图所示。

Bean Creation Life-Cycle Callback

这3个步骤发生在Bean创建生命周期回调中:

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

该图来自 Pro Spring 5:Spring框架及其工具的深入指南

答案 4 :(得分:1)

完整代码在这里:https://github.com/wkaczurba/so8519187 spring-boot

使用注释:

@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
    }
}

获取我们:

  

刷新org.springframework.context ...

     

构造函数中的MyComponent:[null]
   postConstruct中的MyComponent:[魔术]
   afterPropertiesSet中的MyComponent:[魔术]
  ...
  
  在启动时注册Bean以进行JMX公开
  在0.561秒内启动DemoApplication(JVM运行1.011)
  关闭org.springframework.context ...关闭时注销JMX暴露的bean
  
  ...
   PreDestroy中的MyComponent:[魔术]

答案 5 :(得分:1)

@PostConstructinit-method之间可能存在差异,因为@PostConstruct是在bean初始化的postProcessAfterInitialization阶段({{1} }方法),而AbstractAutowireCapableBeanFactory.initializeBean()CommonAnnotationBeanPostProcessor阶段完成之后被调用(并且为此,在init-method阶段开始之前被调用)。
(因此,来自已接受答案的声明

  

@PostConstruct,初始化方法是BeanPostProcessors

不太正确:postProcessBeforeInitializationpostProcessAfterInitialization处理,@PostConstruct不是。)
如果配置为在BeanPostProcessor之后执行(init-method)的某些{潜在地自定义的} BeanPostProcessor在其{ {1}}方法。
默认的Spring配置Ordered.getOrder()没什么不同,因为配置为在CommonAnnotationBeanPostProcessor之后执行的所有postProcessBeforeInitialization都不做任何事情BeanPostProcessors方法。
总而言之,在99%的情况下,可接受的答案和类似的方法都是正确的……并且,这篇文章旨在向“细节中的魔鬼”表示敬意