Spring @PostConstruct 与 init-method 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8519187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @PostConstruct vs. init-method attribute
提问by Jan Zyka
Is there any difference between using the @PostConstructannotation and declaring the same method as init-methodin Spring XML configuration?
使用@PostConstruct注解和声明与init-methodSpring XML 配置相同的方法有什么区别吗?
回答by Aravind A
No practically I don't think there is any difference but there are priorities in the way they work. @PostConstruct, init-methodare BeanPostProcessors.
不,实际上我认为没有任何区别,但它们的工作方式有优先级。@PostConstruct,init-method是 BeanPostProcessors。
@PostConstructis a JSR-250 annotation whileinit-methodis Spring's way of having an initializing method.- If you have a
@PostConstructmethod, this will be called first before the initializing methods are called. - If your bean implements InitializingBean and overrides
afterPropertiesSet, first@PostConstructis called, then theafterPropertiesSetand theninit-method.
@PostConstruct是 JSR-250 注释,init-method而是 Spring 具有初始化方法的方式。- 如果你有一个
@PostConstruct方法,这将在调用初始化方法之前首先被调用。 - 如果你的bean实现的InitializingBean和覆盖
afterPropertiesSet,首先@PostConstruct被调用,然后afterPropertiesSet再init-method。
For more info you can check Spring's reference documentation.
有关更多信息,您可以查看 Spring 的参考文档。
Before JSR 250 specs , usage of init-method in xml was preferred way , as it decouples java classes (beans) from any spring specific classes/annotations.So if you are building a library that does not need to be dependent on spring infrastructure beans then use of init-method was preferred.During creation method u can specify the method that needs to be called as initialization method.
在 JSR 250 规范之前,在 xml 中使用 init-method 是首选方式,因为它将 java 类(bean)与任何 Spring 特定的类/注释解耦。因此,如果您正在构建一个不需要依赖于 Spring 基础设施 bean 的库那么首选使用init-method。在创建方法期间,您可以指定需要调用的方法作为初始化方法。
Now with introduction of JSR 250 specs in Java EE and spring support of these annotations , dependency on spring framework has been reduced to a certain extent.
现在随着 Java EE 中 JSR 250 规范的引入以及这些注解的 spring 支持,对 spring 框架的依赖已经在一定程度上减少了。
But i have to admit that addition of these things increase the readability of code.So there are pros and cons both approaches.
但我不得不承认,添加这些东西会增加代码的可读性。所以这两种方法都有利有弊。
回答by Donal Fellows
There's no real difference. It's down to how you prefer to configure your system, and that's a matter of personal choice. Myself, I prefer to use @PostConstructannotations for my own code (as the bean is only correctly configured after the method is called) and I use init-methodwhen instantiating beans from non-Spring-aware libraries (can't apply annotations there, of course!) but I can totally understand people wanting to do it all one way or the other.
没有真正的区别。这取决于您喜欢如何配置系统,这是个人选择的问题。我自己,我更喜欢@PostConstruct对我自己的代码使用注释(因为只有在调用方法后才能正确配置 bean)并且我init-method在从非 Spring 感知库实例化 bean 时使用(当然不能在那里应用注释!)但我完全可以理解人们想要以一种或另一种方式做到这一切。
回答by Amruth M Raj
@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 .
@postconstruct 不是春天的一部分。它是 javax 包的一部分。两者都是一样的。使用 init-method 我们需要在 xml 文件中添加。如果您使用 @postconstruct 添加在 xml 中不是必需的。看看下面的文章。
回答by yashjain12yj
As you can see in the below diagram of Bean Creation Life-Cycle Callback.
正如您在下面的Bean 创建生命周期回调图中所见。
This 3 step happens in the Bean Creation Life-Cycle Callback:
这 3 个步骤发生在 Bean 创建生命周期回调中:
- It is mentioned that
@PostConstructwill be called. - If
InitializingBeanis implemented, thenafterPropertiesSet()will be called. - If bean definition contains
init-methodor@Bean(initmethod="..")then it calls the init method.
- 提到
@PostConstruct会被调用。 - 如果
InitializingBean实现,afterPropertiesSet()则将被调用。 - 如果 bean 定义包含
init-methodor@Bean(initmethod="..")则调用 init 方法。
This diagram is from Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools
这张图来自Pro Spring 5: An In-Depth Guide to the Spring Framework 及其工具
回答by Witold Kaczurba
Full code here: https://github.com/wkaczurba/so8519187(spring-boot)
完整代码在这里:https: //github.com/wkaczurba/so8519187(spring-boot)
Using annotations:
使用注解:
@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:
得到我们:
Refreshing org.springframework.context...
MyComponent in constructor: [null]
MyComponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [Magic]
...
Registering beans for JMX exposure on startup
Started DemoApplication in 0.561 seconds (JVM running for 1.011)
Closing org.springframework.context... Unregistering JMX-exposed beans on shutdown
...
MyComponent in preDestroy: [Magic]
正在刷新 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:[魔术]
回答by igor.zh
There might bedifference between @PostConstructand init-methodbecause @PostConstructis handled in the postProcessAfterInitializationphase of bean initialization (AbstractAutowireCapableBeanFactory.initializeBean()method) by CommonAnnotationBeanPostProcessor, while initmethod gets called after the completion of postProcessBeforeInitializationphase (and, for this matter, before the beginning of postProcessAfterInitializationphase).
EDIT:
So, the sequence is:
1) postProcessBeforeInitializationphase,
2) initmethod gets called,
3) postProcessAfterInitializationphase, which calls @PostConstructmethod
有可能是差异之间@PostConstruct并init-method因为 @PostConstruct在被处理postProcessAfterInitialization豆初始化(相AbstractAutowireCapableBeanFactory.initializeBean()法)的CommonAnnotationBeanPostProcessor,而init方法被完成后调用postProcessBeforeInitialization(开始之前,并且对于这件事情,相postProcessAfterInitialization相)。
编辑:所以,顺序是:1)postProcessBeforeInitialization阶段,2)init方法被调用,3)postProcessAfterInitialization阶段,调用@PostConstruct方法
(As a side note, a statement from the accepted answer
(作为旁注,来自已接受答案的声明
@PostConstruct, init-method are BeanPostProcessors
@PostConstruct, init-method 是 BeanPostProcessors
is not quite correct: @PostConstructis handled by a BeanPostProcessor, initmethod is not.)
不太正确:@PostConstruct由 a 处理BeanPostProcessor,init方法不是。)
There will bedifference if some (potentially custom) BeanPostProcessor, which is configured with (Ordered.getOrder()) to be executed after CommonAnnotationBeanPostProcessor, is doing something serious in its postProcessBeforeInitializationmethod.
There is noany difference with the default Spring configuration of BeanPostProcessorsbecause all the BeanPostProcessorswhich are configured to be executed after CommonAnnotationBeanPostProcessor, don't do anything in postProcessBeforeInitializationmethod.
有会差一些,如果(潜在的自定义)BeanPostProcessor,其配置有(Ordered.getOrder())后执行CommonAnnotationBeanPostProcessor,是做一些在其严重的postProcessBeforeInitialization方法。
有没有用默认的Spring配置任何区别BeanPostProcessors,因为所有的BeanPostProcessors这些配置后要执行CommonAnnotationBeanPostProcessor,不执行任何操作postProcessBeforeInitialization方法。
In conclusion, the accepted answer and the similar are right ... in 99% of the cases, and this post is just to pay a tribute to a concept "devil is in the details"
总之,接受的答案和类似的答案是正确的......在99%的情况下,这篇文章只是向“魔鬼在细节中”的概念致敬


