1. 程式人生 > >4、SSM框架-Spring中的Bean(4)

4、SSM框架-Spring中的Bean(4)

1.當呼叫者通過getBean(beanName)向容器請求某一個Bean時,如果容器註冊了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor介面,在例項化Bean之前,將呼叫介面的postProcessBeforeInstantiation()方法;

2.根據配置情況呼叫Bean建構函式或工廠方法例項化Bean;

3.如果容器註冊了InstantiationAwareBeanPostProcessor介面,在例項化Bean之後,呼叫該介面的postProcessAfterInstantiation()方法,可在這裡對已經例項化的物件進行一些"梳妝打扮";

4.如果Bean配置了屬性資訊,容器在這一步著手將配置值設定到Bean對應的屬性中,不過在設定每個屬性之前將先呼叫InstantiationAwareBeanPostProcessor介面的postProcessPropertyValues()方法;

2.2 初始化和使用bean


1:BeanNameAware的setBeanName():

如果Bean類有實現org.springframework.beans.BeanNameAware介面,工廠呼叫Bean的setBeanName()方法傳遞Bean的ID。

2:BeanFactoryAware的setBeanFactory():

如果Bean類有實現org.springframework.beans.factory.BeanFactoryAware介面,工廠呼叫setBeanFactory()方法傳入工廠自身。

3:BeanPostProcessors的ProcessBeforeInitialization()

如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean關聯,那麼其postProcessBeforeInitialization()方法將被將被呼叫。

4:initializingBean的afterPropertiesSet():

如果Bean類已實現org.springframework.beans.factory.InitializingBean介面,則執行他的afterProPertiesSet()方法

5:Bean定義檔案中定義init-method:

可以在Bean定義檔案中使用"init-method"屬性設定方法名稱例如:

如果有以上設定的話,則執行到這個階段,就會執行initBean()方法

6:BeanPostProcessors的ProcessaAfterInitialization()

如果有任何的BeanPostProcessors例項與Bean例項關聯,則執行BeanPostProcessors例項的ProcessaAfterInitialization()方法

BeanPostProcessor後處理器定義了兩個方法:

        其一是postProcessBeforeInitialization()在第8步呼叫;其二是Object postProcessAfterInitialization(Object bean, String beanName)方法,這個方法在此時呼叫,容器再次獲得對Bean進行加工處理的機會;

        如果在<bean>中指定Bean的作用範圍為scope="prototype",將Bean返回給呼叫者,呼叫者負責Bean後續生命的管理,Spring不再管理這個Bean的生命週期。如果作用範圍設定為scope="singleton",則將Bean放入到Spring IoC容器的快取池中,並將Bean引用返回給呼叫者,Spring繼續對這些Bean進行後續的生命管理;

2.2 銷燬bean

此時,Bean已經可以被應用系統使用,並且將保留在BeanFactory中知道它不在被使用。有兩種方法可以將其從BeanFactory中刪除掉

1:DisposableBean的destroy()

在容器關閉時,如果Bean類有實現org.springframework.beans.factory.DisposableBean介面,則執行他的destroy()方法

2:Bean定義檔案中定義destroy-method

在容器關閉時,可以在Bean定義檔案中使用"destroy-method"屬性設定方法名稱,例如:

如果有以上設定的話,則進行至這個階段時,就會執行destroy()方法,如果是使用ApplicationContext來生成並管理Bean的話則稍有不同,使用ApplicationContext來生成及管理Bean例項的話,在執行BeanFactoryAware的setBeanFactory()階段後,若Bean類上有實現org.springframework.context.ApplicationContextAware介面,則執行其setApplicationContext()方法,接著才執行BeanPostProcessors的ProcessBeforeInitialization()及之後的流程。

三、Beanfactory中bean生命週期例項

下面我們來看看一個例項吧,自己新建一個工程,匯入需要的Spring包,然後建立如下Worker.java(這裡是bean初始化和使用時會用到的函式 )
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. package com.mucfc.beanlive;  
  2. import org.springframework.beans.BeansException;  
  3. import org.springframework.beans.factory.BeanFactory;  
  4. import org.springframework.beans.factory.BeanFactoryAware;  
  5. import org.springframework.beans.factory.BeanNameAware;  
  6. import org.springframework.beans.factory.DisposableBean;  
  7. import org.springframework.beans.factory.InitializingBean;  
  8. //①管理Bean生命週期的介面     
  9. public class Worker implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean{  
  10.     private String name;  
  11.     private String workType;  
  12.     private int salary;  
  13.     public BeanFactory beanFactory;  
  14.     private String beanName;  
  15.     public void Worker(){  
  16.         System.out.println("呼叫worker()建構函式");  
  17.     }  
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.     public String getWorkType() {  
  25.         return workType;  
  26.     }  
  27.     public void setWorkType(String workType) {  
  28.         this.workType = workType;  
  29.     }  
  30.     public int getSalary() {  
  31.         return salary;  
  32.     }  
  33.     public void setSalary(int salary) {  
  34.         this.salary = salary;  
  35.     }  
  36.      public void printInfo() {      
  37.             System.out.println("name:" + name + ";workType:" + workType + ";salary:"      
  38.                     + salary);      
  39.         }      
  40.      //⑤DisposableBean介面方法      
  41.     @Override  
  42.     public void destroy() throws Exception {  
  43.         System.out.println("----------------銷燬bean----------------------");  
  44.          System.out.println("呼叫DisposableBean.destroy()。");      
  45.     }  
  46.      //④InitializingBean介面方法      
  47.     @Override  
  48.     public void afterPropertiesSet() throws Exception {  
  49.          System.out.println("呼叫InitializingBean.afterPropertiesSet()。");     
  50.     }  
  51.      //③BeanNameAware介面方法      
  52.     @Override  
  53.     public void setBeanName(String arg0) {  
  54.         System.out.println("----------------初始化bean----------------------");  
  55.          System.out.println("呼叫BeanNameAware.setBeanName()。");      
  56.             this.beanName = arg0;      
  57.     }  
  58.      //②BeanFactoryAware介面方法      
  59.     @Override  
  60.     public void setBeanFactory(BeanFactory arg0) throws BeansException {  
  61.          System.out.println("呼叫BeanFactoryAware.setBeanFactory()。");      
  62.          this.beanFactory = arg0;      
  63.     }  
  64.     //⑥通過<bean>的init-method屬性指定的初始化方法      
  65.     public void myInit() {      
  66.         System.out.println("呼叫init-method所指定的myInit(),將salary設定為600。");      
  67.         this.salary = 600;      
  68.     }      
  69.      //⑦通過<bean>的destroy-method屬性指定的銷燬方法      
  70.     public void myDestroy() {      
  71.         System.out.println("呼叫destroy-method所指定的myDestroy()。");      
  72.     }      
  73. }  
Worker類在②、③、④、⑤處實現了BeanFactoryAware、BeanNameAware、InitializingBean、DisposableBean這些Bean級的生命週期控制介面;在⑥和⑦處定義了myInit()和myDestroy()方法,以便在配置檔案中通過init-method和destroy-method屬性定義初始化和銷燬方法。