在Spring XML配置中使用@PostConstruct
注释和声明与init-method
相同的方法之间有什么区别吗?
答案 0 :(得分:142)
实际上,我并不认为存在任何差异,但工作方式有优先考虑。 @PostConstruct
,init-method
是BeanPostProcessors。
@PostConstruct
是JSR-250注释,而init-method
是Spring的初始化方法。@PostConstruct
方法,则会在调用初始化方法之前先调用此方法。afterPropertiesSet
,则先调用@PostConstruct
,然后调用afterPropertiesSet
,然后调用init-method
。有关详细信息,您可以查看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中添加。请查看以下文章。
答案 3 :(得分:2)
如下面的 Bean创建生命周期回调图所示。
这3个步骤发生在Bean创建生命周期回调中:
@PostConstruct
将被呼叫。InitializingBean
,那么将调用afterPropertiesSet()
。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)
@PostConstruct
和init-method
之间可能存在差异,因为@PostConstruct
是在bean初始化的postProcessAfterInitialization
阶段({{1} }方法),而AbstractAutowireCapableBeanFactory.initializeBean()
在CommonAnnotationBeanPostProcessor
阶段完成之后被调用(并且为此,在init-method
阶段开始之前被调用)。
(因此,来自已接受答案的声明
@PostConstruct,初始化方法是BeanPostProcessors
不太正确:postProcessBeforeInitialization
由postProcessAfterInitialization
处理,@PostConstruct
不是。)
如果配置为在BeanPostProcessor
之后执行(init-method
)的某些{潜在地自定义的} BeanPostProcessor
在其{ {1}}方法。
默认的Spring配置Ordered.getOrder()
与没什么不同,因为配置为在CommonAnnotationBeanPostProcessor
之后执行的所有postProcessBeforeInitialization
都不做任何事情BeanPostProcessors
方法。
总而言之,在99%的情况下,可接受的答案和类似的方法都是正确的……并且,这篇文章旨在向“细节中的魔鬼”表示敬意