Spring Bean的生命週期

 

Spring容器能夠管理singleton做用域的Bean的生命週期,能夠調用建立、初始化、銷燬等生命週期的方法。緩存

對於prototype做用域的Bean,Spring容器只負責建立,建立後Bean的實例就交給客戶端代碼來管理,Spring容器再也不跟蹤其生命週期。app

 

 

Bean的生命週期

一、根據配置狀況,調用Bean的構造方法或工廠方法實例化Beanide

二、利用依賴注入完成Bean中全部屬性值的配置注入post

 

三、若是Bean實現了BeanNameAware接口,則調用setBeanName()方法傳入當前Bean的id。this

四、若是Bean實現了BeanFactoryAware接口,則調用setBeanFactory()傳入當前工廠實例的引用spa

五、若是Bean實現了ApplicationContextAware接口,則調用setApplicationContext()方法傳入當前ApplicationContext實例的引用prototype

 

六、若是BeanPostProcessor和Bean關聯,則調用預初始化方法postProcessBeforeInitialzation()進行加工操做,Spring AOP即利用此實現。code

 

七、若是Bean實現了InitializingBean接口,則調用afterPropertiesSet()方法xml

八、若是在配置文件中經過init-method屬性指定了初始化方法,則調用初始化方法blog

 

九、若是BeanPostProcessor和Bean關聯,則調用初始化方法postProcessAfterInitialization()。此時,Bean已經能夠被正常使用了。

 

十、若是指定了做用域爲singleton,則將實例放在Spring IoC的緩存池中,並觸發Spring容器對該Bean的生命週期管理,若是指定做用域爲prototype,則將該Bean交給調用者,由調用者管理該Bean的生命週期。

 

十一、若是Bean實現了DisposableBean接口,則調用destory()方法銷燬實例;

十二、若是在配置文件中經過destory-method指定了Bean的銷燬方法,則調用該方法銷燬實例。

 

 

說明:

以上接口中,均只有一個方法。

並不建議讓Bean實現多個接口,由於繼承多個接口會使代碼耦合較高。

 

 

 

 

注入依賴後的行爲

Spring提供2種方式,在Bean所有屬性設置完成後執行特定的行爲:

  • 實現InitializingBean接口,在afterPropertiesSet()方法中寫代碼。InitializingBean接口中只有這一個方法。
  • 在xml中使用init-method屬性指定要調用的方法

能夠同時使用這2種方式,會先執行afterPropertiesSet(),再執行init-method屬性指定的方法。

 

 

 

Bean銷燬以前的行爲

Spring提供了2種方式,在Bean銷燬以前執行特定的行爲:

  • 實現DisposableBean接口,該接口只有destory()方法
  • 在xml中用destory-method屬性指定要調用的方法

能夠同時使用這2種方式,會先執行destory(),再執行destory-method屬性指定的方法。

 

說明:同時使用時,都是先執行接口中的方法,再執行xml中指定的方法。

 

 

 

示例

 1 class Student {
 2     private String name;
 3 
 4     public Student(String name){
 5         this.name=name;
 6     }
 7 
 8     public String getName(){
 9         return name;
10     }
11 }
12 
13 class Teacher implements InitializingBean, DisposableBean {
14     @Autowired
15     private Student student;
16 
17     public void say(){
18         System.out.println(student.getName()+",叫家長來一下");
19     }
20 
21     public void xmlInit(){
22         System.out.println("正在執行xml中init-method屬性指定的初始化方法");
23     }
24 
25     @Override
26     public void afterPropertiesSet() throws Exception {
27         System.out.println("正在執行InitializingBean接口中的afterPropertiesSet()方法");
28     }
29 
30     public void xmlDestory(){
31         System.out.println("正在執行xml中destory-method屬性指定的方法");
32     }
33 
34     @Override
35     public void destroy() throws Exception {
36         System.out.println("正在執行DisposableBean接口中的destory()方法");
37     }
38 }
39 
40 public class Test {
41     public static void main(String[] args) {
42         AbstractApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
43         Teacher teacher=applicationContext.getBean("teacher",Teacher.class);
44         teacher.say();
45         applicationContext.registerShutdownHook();
46     }
47 
48 }

在基於Web的Spring容器中,系統已經提供了相應的代碼,在Web應用關閉時,會自動關閉Spring容器。

在非Web的Spring的容器中,須要手動調用AbstractApplicationContext類的registerShutdownHook()方法向JVM註冊一個關閉鉤子,執行完前面的代碼,會自動關閉Spring容器。

ApplicatioContext即Spring容器。

ApplicationContext是接口,沒有實現registerShutdownHook()方法,AbstractApplicationContext是ApplicationContext的子類,實現了該方法,此處要聲明爲AbstractApplicationContext,不能聲明爲ApplicationContext。

 

 

xml中的配置:

    <context:annotation-config />

    <bean id="student" class="my_package.Student">
        <constructor-arg value="張三" />
    </bean>

    <bean id="teacher" class="my_package.Teacher" init-method="xmlInit" destroy-method="xmlDestory" />

 

 

運行程序,控制檯輸出以下:

正在執行InitializingBean接口中的afterPropertiesSet()方法
正在執行xml中init-method屬性指定的初始化方法
張三,叫家長來一下
正在執行DisposableBean接口中的destory()方法
正在執行xml中destory-method屬性指定的方法
相關文章
相關標籤/搜索