什么情况才需要通过容器回调的方式处理bean?
- 有一些操作不适合在构造函数中处理的情况
- 监控某个bean是否被初始化,在初始化完成后,容器关闭前做一些业务操作
方式一:InitializingBean/DisposableBean
InitializingBean
表示bean实例化完成后的回调接口,DisposableBean
表示bean销毁前的回调接口
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
void destroy() throws Exception;
}
方式二:@Bean
通过@Bean
中的属性自,自定义回调方法,init-method
在singleton bean 先调用构造,在调用自定义的初始化方法,prototype bean IoC容器初始化时不调用init-method,每次获取bean时调用,destroy-method
singleton bean 必须显示调用容器的close(),才会执行destroy(),prototype bean 容器不负责销毁
// 自定义bean初始化完成后的回调方法initMthod,销毁前的回调方法destroyMethod
@Bean(initMethod = "initMthod", destroyMethod = "destroyMethod")
方式三:JSR250 @PostConstruct/@PreDestory
这两个注解不是spring官方的注解,但是spring也支持,这两个注解在package javax.annotation
包下,标注在方法上,实现回调操作
@PostConstruct
public void postConstruct(){
System.out.println("@PostConstruct");
}
@PreDestroy
public void preDestory(){
System.out.println("@PreDestroy");
}
方式四:BeanPostProcessor
通过实现org.springframework.beans.factory.config.BeanPostProcessor
接口,在对象初始化前后执行一些自定义操作,准确的说BeanPostProcessor不应该算在声明周期的回调的方式中,但BeanPostProcessor确实可以在bean实例话前、后做一些针对bean的扩展操作,所以就放在一起说明,postProcessBeforeInitialization()
在bean初始化之前被调用,postProcessAfterInitialization()
在bean初始化完成后被调用
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
顺序
如果以上四种方式都对一个bean使用了,四种方式的加载顺序如何呢?
构造->BeanPostProcessor->JSR 250->InitializingBean->@Bean
Constructor Car // bean构造
postProcessBeforeInitialization //BeanPostProcessor
@PostConstruct //JSR250
InitializingBean // 接口
init-method //@Bean
postProcessAfterInitialization //BeanPostProcessor
@PreDestroy //JSR250
DisposableBean // 接口
destroy-method //@Bean
网友评论