天天看點

Spring Bean的生命周期管理(上)1 Spring簡介2 Bean對象生命周期管理initialization 和 destroy

1 Spring簡介

  • 輕量級容器,提供集中式,自動配置與裝配應用業務對象功能
  • 提供統一的事務管理抽象,基于插件式的事務管理(聲明性事務管理)能夠很容易的實作事務層管理,而無需了解底層事務實作
  • 提供統一的資料通路抽象,包括簡單和有效率的JDBC架構,極大的改進了效率(大大減少了開發的代碼量)并且減少了可能的錯誤
  • Spring的資料通路層內建了Toplink,Hibernate,JDO,and iBATIS SQL Maps等O/R mapping解決方案,其目的是提供統一的DAO支援類實作和事務管理政策
  • Spring提供了一個用标準Java編寫的AOP架構(也能內建AspectJ),提供基于POJOs的聲明式的事務管理和其他企業事務
  • 提供可以與IoC容器內建的強大而靈活的MVCWeb架構
Spring Bean的生命周期管理(上)1 Spring簡介2 Bean對象生命周期管理initialization 和 destroy

2 Bean對象生命周期管理

Spring Bean的生命周期管理(上)1 Spring簡介2 Bean對象生命周期管理initialization 和 destroy

1 Spring對Bean進行執行個體化

相當于new Class()

2 Spring将值和Bean的引用注進Bean對應的屬性

3 實作BeanNameAware接口

  • Spring将Bean的ID傳遞給setBeanName()方法
  • 實作BeanNameAware主要為了通過Bean的引用獲得Bean的ID,一般業務中是很少有用到Bean的ID

4 實作BeanFactoryAware接口

  • Spring将調用setBeanDactory(BeanFactory bf),并把BeanFactory容器執行個體作為參數傳入
  • 實作BeanFactoryAware 主要為了擷取Spring容器,如Bean通過Spring容器釋出事件

5 實作ApplicationContextAwaer接口

Spring容器将調用setApplicationContext(ApplicationContext ctx),把應用上下文作為參數傳入。

與BeanFactory類似都為擷取Spring容器,不同是

Spring容器在調用setApplicationContext方法時會把它自己作為setApplicationContext 的參數傳入

而Spring容器在調用setBeanDactory前需要程式員自己指定(注入)setBeanDactory裡的參數BeanFactory

6 BeanPostProcess接口

Spring将調用它們的postProcessBeforeInitialization(預初始化)方法,在Bean執行個體建立成功後對進行增強處理,如對Bean進行修改,增加某個功能。

7 InitializingBean接口

為bean提供了初始化方法的方式。

隻含afterPropertiesSet方法,凡是繼承該接口的類,在初始化bean時會自動執行該方法。

Spring将調用它們的afterPropertiesSet方法,作用與在配置檔案中對Bean使用init-method聲明初始化同效,都是在Bean的全部屬性設定成功後,執行的初始化方法。

實作InitializingBean接口是直接調用afterPropertiesSet方法,比通過反射調用init-method指定的方法相對來說效率要高。但init-method方式消除了對spring的依賴

若調用afterPropertiesSet方法時産生異常,則不會再調用init-method指定的方法

package org.springframework.beans.factory;

/**
 * 所有由BeanFactory設定的所有屬性都需要響應的bean的接口:例如,執行自定義初始化,或者隻是檢查所有強制屬性是否被設定。
 * 實作InitializingBean的替代方法是指定一個自定義init方法,例如在XML bean定義中。
 */
public interface InitializingBean {

    /**
     * 在BeanFactory設定了提供的所有bean屬性後,由BeanFactory調用。 
     *這個方法允許bean執行個體在所有的bean屬性被設定時才能執行
     */
    void afterPropertiesSet() throws Exception;

}      

若class中實作該接口,在Spring Container中的bean生成之後,自動調用函數afterPropertiesSet()。

因其實作了InitializingBean接口,其中隻有一個方法,且在Bean加載後就執行。該方法可被用來檢查是否所有的屬性都已設定好。

8 BeanPostProcess接口

Spring将調用它們的postProcessAfterInitialization(後初始化)方法,作用與6一樣,隻不過6是在Bean初始化前執行,而這是在Bean初始化後執行。

經過以上工作,Bean将一直駐留在應用上下文中給應用使用,直到應用上下文被銷毀。

9 DispostbleBean接口

  • Spring将調用它的destory方法
  • 作用與在配置檔案中對Bean使用destory-method屬性的作用一樣,都是在Bean執行個體銷毀前執行的方法

Spring Bean是Spring應用中最最重要的部分了。是以來看看Spring容器在初始化一個bean的時候會做那些事情,順序是怎樣的,在容器關閉的時候,又會做哪些事情。

Spring容器初始化
=====================================
調用GiraffeService無參構造函數
GiraffeService中利用set方法設定屬性值
調用setBeanName:: Bean Name defined in context=giraffeService
調用setBeanClassLoader,ClassLoader Name = sun.misc.Launcher$AppClassLoader
調用setBeanFactory,setBeanFactory:: giraffe bean singleton=true
調用setEnvironment
調用setResourceLoader:: Resource File Name=spring-beans.xml
調用setApplicationEventPublisher
調用setApplicationContext:: Bean Definition Names=[giraffeService, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0, com.giraffe.spring.service.GiraffeServicePostProcessor#0]
執行BeanPostProcessor的postProcessBeforeInitialization方法,beanName=giraffeService
調用PostConstruct注解标注的方法
執行InitializingBean接口的afterPropertiesSet方法
執行配置的init-method
執行BeanPostProcessor的postProcessAfterInitialization方法,beanName=giraffeService
Spring容器初始化完畢
=====================================
從容器中擷取Bean
giraffe Name=JavaEdge
=====================================
調用preDestroy注解标注的方法
執行DisposableBean接口的destroy方法
執行配置的destroy-method
Spring容器關閉      

先來看看,Spring在Bean從建立到銷毀的生命周期中可能做得事情。

initialization 和 destroy

有時需要在Bean屬性值set好後、Bean銷毀前搞事情,比如檢查Bean中某個屬性是否被正常設值。

Spring提供了多種方法讓我們可以在 Bean 的生命周期中執行initialization和pre-destroy方法。

1 實作InitializingBean/DisposableBean接口

這兩個接口都隻包含一個方法:

  • 實作InitializingBean#afterPropertiesSet(),可在Bean屬性值設定好後操作
  • 實作DisposableBean#destroy(),可在銷毀Bean前操作

案例

public class GiraffeService implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("執行InitializingBean接口的afterPropertiesSet方法");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("執行DisposableBean接口的destroy方法");
    }
}
      

這種使用比較簡單,但不推薦,會将Bean實作和Spring架構耦合。