springBoot中Bean的生命周期

springboot中Bean的生命周期

今天主要分享一下Springboot中Bean的生命周期的過程,如有不足,歡迎指正交流。

Bean生命周期的過程

Bean生命周期一般有下面的四個階段:

  • Bean的定義

  • Bean的初始化

  • Bean的生存期

  • Bean的銷毀

Bean的定義過程:

  1. 第一步,資源定位,就是Spring根據我們定義的註解(@Component),找到相應的類。

  2. 找到了資源就開始解析,並將定義的資訊保存起來,此時,並沒有初始化bean,這點需要注意。

  3. 然後將bean的定義發布到SpringIoc的容器中,此時,SpringIoc的容器中還是沒有Bean的生成。只是定義的資訊。

Bean的初始化

經過Bean的定義,初始化,SPring會繼續完成Bean的實例和化和依賴注入,這樣從IoC容器中就可以得到一個依賴注入完成的Bean。下圖是初始化圖的示例:

Spring初始化Bean

Bean的生命周期

Spring中Bean的生命周期

通過程式碼測試Bean的生命周期

加入生命周期的介面

   BeanNameAware,BeanFactoryAware,ApplicationContextAware,INitiali
   zingBean,DisposableBean這幾個介面, 並實現裡面的方法

程式碼實現

環境: jdk 1.8 springboot2.2 idea

  1. 定義介面Person類和Furit類

       package chen.beanprocessor.model;
    
       public interface Person {
        
       void service();
      
        // 設置水果類型
        void eatFruit(Fruit fruit);
        }  
    
       /**
        * @Author Chen
        * @Date 2020/4/18 17:04
        **/
        public interface Fruit {
        void use();
        }
    
  2. 定義Person和Fruit的實現類Children和Apple,並將Apple類注入到Children中,在Children中加入生命那個周期的介面:

      /**
       * @Author Chen
       * @Date 2020/4/18 17:07
       * 水果實現類Apple
       **/
       @Component
       public class Apple implements Fruit {
       @Override
       public void use() {
       System.out.println(this.getClass().getSimpleName()+"這個蘋果很甜");
       }
       }
    
     @Component
     public class Children implements Person, BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
    
     Fruit fruit = null;
    
     // 注入水果類
     public Children(@Autowired Fruit fruit){
      this.fruit = fruit;
     }
     @Override
     public void service() {
     fruit.use();
     }
    
     @Override
     public void eatFruit(Fruit fruit) {
     this.fruit = fruit;
     }
    
    
     @Override
      public void setBeanFactory(BeanFactory beanFactory) throws BeansException   {
      System.out.println("this"+this.getClass().getSimpleName()+"調用BeanFactory的setBeanFactory方法");
      }
    
      @Override
      public void setBeanName(String name) {
      System.out.println("this"+this.getClass().getSimpleName()+"調用setBeanName的方法");
      }
    
      @Override
      public void destroy() throws Exception {
      System.out.println("this"+this.getClass().getSimpleName()+"調用DisposableBean的方法");
      }
    
      @Override
       public void afterPropertiesSet() throws Exception {
       System.out.println("this"+this.getClass().getSimpleName()+"調用Initializing的afterPropertiesSet()的方法");
       }
    
     @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println("this"+this.getClass().getSimpleName()+"調用Application的setApplicationContext的方法");
     }
    
    @PostConstruct
    public void init(){
    
     System.out.println(this.getClass().getSimpleName()+"註解@PostConstruct的自定義的初始化方法");
    }
    
     @PreDestroy
    public void destory1(){
    System.out.println(this.getClass().getSimpleName()+"調用@dPrDestory的自定義銷毀的方法");
    }
    
    }
    

3.定義測試類

      @SpringBootApplication
     public class BeanprocessorApplication {

     public static void main(String[] args) {
     SpringApplication.run(BeanprocessorApplication.class, args);
     AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
     Person person = applicationContext.getBean(Children.class);
     System.out.println("===========初始化完成==========");
     person.service();
     applicationContext.close();
     }
    }

測試結果

 thisChildren調用setBeanName的方法
 thisChildren調用BeanFactory的setBeanFactory方法
 thisChildren調用Application的setApplicationContext的方法
 Children註解@PostConstruct的自定義的初始化方法
 thisChildren調用Initializing的afterPropertiesSet()的方法

 2020-04-18 17:28:38.902  INFO 9784 --- [           main] c.b.BeanprocessorApplication             : Started BeanprocessorApplication in 0.682 seconds (JVM running for 1.29)
 thisChildren調用setBeanName的方法
 thisChildren調用BeanFactory的setBeanFactory方法
 thisChildren調用Application的setApplicationContext的方法
 Children註解@PostConstruct的自定義的初始化方法
 thisChildren調用Initializing的afterPropertiesSet()的方法

 ===========初始化完成==========
 Apple這個蘋果很甜


 Children調用@dPrDestory的自定義銷毀的方法
 thisChildren調用DisposableBean的方法
 Children調用@dPrDestory的自定義銷毀的方法
 thisChildren調用DisposableBean的方法

測試結果可以清晰的看到bean的生命周期的過程。從測試結果來看,Bean被初始化了兩次,這是因為在初始化Children這個類時,還初始化了注入的Apple這個類。

碼字不易,點個讚唄

碼字不易,點個讚唄

碼字不易,點個讚唄

追本溯源,方能闊步前行

參考資料:

《深入淺出SpringBoot》 楊開振