Spring Bean声明周期回调方式

2019-10-26  本文已影响0人  木山手札

什么情况才需要通过容器回调的方式处理bean?

  1. 有一些操作不适合在构造函数中处理的情况
  2. 监控某个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-methodsingleton 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
上一篇下一篇

猜你喜欢

热点阅读