spring bean生命週期

參考連接1:Spring中Bean的生命週期是怎樣的?git

參考連接2:Spring Bean 生命週期github

前言

最近買了幾本書,看了其中講springboot的一本書,看到了講spring bean的生命週期這一節,書上只是提了個大概,感受不是本身想要的結果,仍是本身動手吧;雖然寫得很差,可是記一記仍是對本身有好處的;spring

正文

在網上找了幾張圖,感受有一張比較清楚:springboot

avatar
接下來講一下幾種方式吧,該項目使用springboot構建的;如下代碼均在改項目中完成app

1. 自定義初始化方法和銷燬方法

新建一個bean類,注意該bean類上並無使用註解ide

public class CustomBean {
    private final static Logger logger = LoggerFactory.getLogger(CustomBean.class);
    public void init(){
        logger.info("CustomBean-init");
    }
    public void destroy(){
        logger.info("CustomBean-destroy");
    }
}

自定義bean的初始化和銷燬方法須要在配置文件中添加如下代碼:函數

@Configuration
public class LifeCycleConfig {
    /**
     * 自定義bean的initMethod和destroyMethod
     * @return
     */
    @Bean(initMethod = "init",destroyMethod = "destroy")
    CustomBean customBean(){
        return new CustomBean();
    }
}

2. 使用註解的方式

使用@PostConstruct@PreDestroy兩個註解,其中 @PostConstruct是在構方函數執行完以後指向性,@PreDestroy是在bean銷燬前執行;post

該bean類上使用了Component註解,固然,你還可使用另外的那三個註解中的某一個;code

@Component
public class AnnotationBean {
    private static final Logger logger= LoggerFactory.getLogger(AnnotationBean.class);
    @PostConstruct
    public void init(){
       logger.info("AnnotationBean-init");
    }
    @PreDestroy
    public void destroy(){
        logger.info("AnnotationBean-destroy");
    }
}

3.InitializingBean, DisposableBean

還能夠繼承InitializingBean, DisposableBean接口

@Component
public class LifeCycleBean implements InitializingBean,DisposableBean {
    private static final Logger logger= LoggerFactory.getLogger(LifeCycleBean.class);
    @Override
    public void destroy() throws Exception {
        logger.info("LifeCycleBean-destroy");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("LifeCycleBean-afterPropertiesSet");
    }
}

4.實現*Aware接口

在上邊的圖中可看見,有三個在最前面的三個Aware接口類,這些接口的功能就不用去說了

@Component
public class LifeCycleBeanAware implements BeanNameAware,BeanFactoryAware,ApplicationContextAware {
    private static final Logger logger= LoggerFactory.getLogger(LifeCycleBeanAware.class);
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        logger.info("bean工廠");
    }
    @Override
    public void setBeanName(String s) {
        logger.info("bean的默認的名字:"+s);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        logger.info("bean上下文");
    }
}

5.BeanPostProcessor 加強處理器

這個類不是接口類,這個類中有兩個方法postProcessBeforeInitializationpostProcessAfterInitialization

@Component
public class LifeCycleProcessor implements BeanPostProcessor {
    private static final Logger logger= LoggerFactory.getLogger(LifeCycleProcessor.class);
    private static final String DEFAULT_BEAN_NAME="annotationBean";
    /**
     *在bean初始化以前執行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(DEFAULT_BEAN_NAME.equals(beanName)){
            logger.info("bean初始化以前執行:"+beanName);
        }
        return bean;
    }
    /**
     *bean初始化以後執行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(DEFAULT_BEAN_NAME.equals(beanName)){
            logger.info("bean初始化以後執行:"+beanName);
        }
        return bean;
    }
}

啓動後的結果:

2018-09-08 16:25:55.238  INFO 2584 --- [           main] com.gyc.bean.LifeCycleProcessor          : bean初始化以前執行:annotationBean
2018-09-08 16:25:55.238  INFO 2584 --- [           main] com.gyc.bean.AnnotationBean              : AnnotationBean-init
2018-09-08 16:25:55.238  INFO 2584 --- [           main] com.gyc.bean.LifeCycleProcessor          : bean初始化以後執行:annotationBean
2018-09-08 16:25:55.241  INFO 2584 --- [           main] com.gyc.bean.LifeCycleBean               : LifeCycleBean-afterPropertiesSet
2018-09-08 16:25:55.246  INFO 2584 --- [           main] com.gyc.bean.LifeCycleBeanAware          : bean的默認的名字:lifeCycleBeanAware
2018-09-08 16:25:55.246  INFO 2584 --- [           main] com.gyc.bean.LifeCycleBeanAware          : bean工廠
2018-09-08 16:25:55.246  INFO 2584 --- [           main] com.gyc.bean.LifeCycleBeanAware          : bean上下文
2018-09-08 16:25:55.279  INFO 2584 --- [           main] com.gyc.bean.CustomBean                  : CustomBean-init
2018-09-08 16:25:55.506  INFO 2584 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-09-08 16:25:55.539  INFO 2584 --- [           main] com.gyc.GycApplication                   : Started GycApplication in 1.922 seconds (JVM running for 3.01)
2018-09-08 16:25:55.544  INFO 2584 --- [       Thread-6] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7b227d8d: startup date [Sat Sep 08 16:25:54 CST 2018]; root of context hierarchy
2018-09-08 16:25:55.548  INFO 2584 --- [       Thread-6] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2018-09-08 16:25:55.549  INFO 2584 --- [       Thread-6] com.gyc.bean.CustomBean                  : CustomBean-destroy
2018-09-08 16:25:55.549  INFO 2584 --- [       Thread-6] com.gyc.bean.LifeCycleBean               : LifeCycleBean-destroy
2018-09-08 16:25:55.549  INFO 2584 --- [       Thread-6] com.gyc.bean.AnnotationBean              : AnnotationBean-destroy

示例代碼-github

總結

梳理了bean的生命週期,大概明白了spring對bean的一個處理流程;

對最上邊的圖進行詳細描述:

  1. spring對bean進行實例化
  2. spring 將值和bean的引用注入到bean對應的屬性當中;
  3. 若是bean實現了BeanNameAware接口,spring將bean的ID傳遞給setBeanName方法
  4. 若是bean實現了BeanFactoryAware接口,spring將調用setBeanFactory方法,將BeanFactory容器實例傳入
  5. 若是bean實現了ApplicationContextAware接口,spring容器將調用setApplicationContext方法,將bean所在的應用上下文的引用傳入進來
  6. 若是bean實現的BeanPostProcessor接口,spring將調用他們的postProcessBeforeInitialization方法;
  7. 若是bean實現了InitializeingBean接口,spring將調用他們的afterPropertiesSet方法。相似的,若是bean使用了init-method聲明瞭初始化方法,該方法也會被調用;
  8. 若是bean實現的BeanPostProcessor接口,spring將調用他們的postProcessAfterInitialization方法
  9. bean被應用程序調用,直到該應用上下文被銷燬;
  10. 若是bean實現了DisposableBean接口,spring將調用他的destroy方法。若是bean使用destroy-method聲明銷燬方法,該方法也會被調用
相關文章
相關標籤/搜索