Spring @PostConstruct与init-method属性

Jan*_*yka 94 spring

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

Ara*_*d A 146

实际上,我认为没有任何区别,但它们的工作方式有优先考虑.@PostConstruct,init-method是BeanPostProcessors.

  1. @PostConstruct是一个JSR-250注释,而init-methodSpring是一种初始化方法.
  2. 如果您有@PostConstruct方法,则在调用初始化方法之前首先调用此方法.
  3. 如果你的bean实现的InitializingBean和覆盖afterPropertiesSet,首先@PostConstruct被调用,然后afterPropertiesSetinit-method.

有关更多信息,请查看Spring的参考文档.

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

现在,随着Java EE中JSR 250规范的引入以及对这些注释的弹簧支持,对spring框架的依赖已经减少到一定程度.

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

  • 如果bean使用多种方法并依赖于初始化顺序,那么它将非常复杂且难以维护. (22认同)
  • @Donal很真实.只提供有关其工作原理的信息. (2认同)
  • 有一个重要的区别:您需要专门配置 Spring 来处理注释才能使 @PostConstruct 工作:http://stackoverflow.com/q/3434377/134898 (2认同)

Don*_*ows 19

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


Wit*_*rba 6

完整代码在这里:https : //github.com/wkaczurba/so8519187spring-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
    }
}
Run Code Online (Sandbox Code Playgroud)

得到我们:

正在刷新 org.springframework.context...

MyComponent in constructor: [null]
MyComponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [Magic]
...

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

...
preDestroy 中的 MyComponent:[魔术]


小智 5

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

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


igo*_*.zh 5

和之间可能存在差异,因为 是在bean 初始化(方法)阶段由处理的,而方法是在阶段完成后(并且就此而言,在阶段开始之前)调用的。编辑:所以,顺序是:1)阶段,2)调用方法,3)阶段,调用方法@PostConstructinit-method@PostConstructpostProcessAfterInitializationAbstractAutowireCapableBeanFactory.initializeBean()CommonAnnotationBeanPostProcessorinitpostProcessBeforeInitializationpostProcessAfterInitialization
postProcessBeforeInitializationinitpostProcessAfterInitialization@PostConstruct

(作为旁注,来自已接受答案的声明

@PostConstruct、init-method 是 BeanPostProcessors

不太正确:@PostConstruct由 a 处理BeanPostProcessorinit方法则不是。)

如果某些(可能是自定义的)配置为在之后执行的 ( ) ,在其方法中做了一些严肃的事情,则会有所不同。和默认的 Spring 配置没有任何区别 ,因为所有配置都配置为 after 执行,方法中不做任何事情。BeanPostProcessorOrdered.getOrder()CommonAnnotationBeanPostProcessorpostProcessBeforeInitialization
BeanPostProcessorsBeanPostProcessorsCommonAnnotationBeanPostProcessorpostProcessBeforeInitialization

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