使用@PostConstruct注释和声明与init-methodSpring XML配置中相同的方法之间有什么区别吗?
使用@PostConstruct注释和声明与init-methodSpring XML配置中相同的方法之间有什么区别吗?
Answers:
实际上,我认为没有什么区别,但是它们的工作方式有优先考虑的地方。@PostConstruct,init-method是BeanPostProcessors。
@PostConstruct是JSR-250注释,而init-methodSpring是具有初始化方法的方法。@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]