使用@PostConstruct
注释和声明与init-method
Spring XML配置中相同的方法之间有什么区别吗?
使用@PostConstruct
注释和声明与init-method
Spring XML配置中相同的方法之间有什么区别吗?
Answers:
实际上,我认为没有什么区别,但是它们的工作方式有优先考虑的地方。@PostConstruct
,init-method
是BeanPostProcessors。
@PostConstruct
是JSR-250注释,而init-method
Spring是具有初始化方法的方法。@PostConstruct
方法,将在调用初始化方法之前先调用此方法。afterPropertiesSet
,首先@PostConstruct
被调用,然后afterPropertiesSet
再init-method
。有关更多信息,您可以查看Spring的参考文档。
在JSR 250规范之前,在xml中使用init-method是首选方式,因为它可以将Java类(bean)与任何特定于Spring的类/注释分离。因此,如果要构建不需要依赖Spring基础结构bean的库,那么在创建方法期间,您可以指定需要称为初始化方法的方法。
现在,随着Java EE中的JSR 250规范的引入以及这些注释的Spring支持,对Spring框架的依赖性已在一定程度上降低了。
但是我必须承认,添加这些东西可以提高代码的可读性,因此两种方法都有其优缺点。
@postconstruct不是春天的一部分。它是javax软件包的一部分。两者是相同的。使用init-method我们需要在xml文件中添加。如果使用@postconstruct,则不需要在xml中添加。看看下面的文章。
正如您在Bean创建生命周期回调的下图中所看到的。
这3个步骤发生在Bean创建生命周期回调中:
@PostConstruct
将被称为。InitializingBean
执行,afterPropertiesSet()
则将被调用。init-method
或,@Bean(initmethod="..")
则它将调用init方法。该图来自Pro Spring 5:Spring框架及其工具的深入指南
有可能是差异之间@PostConstruct
并init-method
因为 @PostConstruct
在被处理postProcessAfterInitialization
豆初始化(相AbstractAutowireCapableBeanFactory.initializeBean()
法)的CommonAnnotationBeanPostProcessor
,而init
方法被完成后调用postProcessBeforeInitialization
(开始之前,并且对于这件事情,相postProcessAfterInitialization
相)。
编辑:因此,顺序是:1)postProcessBeforeInitialization
阶段,2)init
方法被调用,3)postProcessAfterInitialization
阶段,调用@PostConstruct
方法
(附带说明,已接受答案的声明
@PostConstruct,初始化方法是BeanPostProcessors
是不是很正确:@PostConstruct
通过处理BeanPostProcessor
,init
方法是不是)。
有会差一些,如果(潜在的自定义)BeanPostProcessor
,其配置有(Ordered.getOrder()
)后执行CommonAnnotationBeanPostProcessor
,是做一些在其严重的postProcessBeforeInitialization
方法。
有没有用默认的Spring配置任何区别BeanPostProcessors
,因为所有的BeanPostProcessors
这些配置后要执行CommonAnnotationBeanPostProcessor
,不执行任何操作postProcessBeforeInitialization
方法。
总而言之,在99%的案例中,可接受的答案和类似的答案都是正确的……并且,该帖子旨在向“细节中的魔鬼”致敬
完整代码在这里: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:[Magic]
afterPropertiesSet中的MyComponent:[Magic]
...
在启动时注册JMX暴露的
bean在0.561秒内启动了DemoApplication(JVM运行1.011)
关闭org.springframework.context。 。关闭时注销JMX暴露的bean
...
preDestroy中的MyComponent:[Magic]