Spring之BeanFactory及Bean生命周期


1、spring通過BeanFactory靈活配置、管理bean,Spring對管理的bean沒有任何特別的要求,完全支持對POJO的管理;

2、BeanFactory有個ApplicationContext子接口,該接口比BeanFactory增強了更多的功能,該接口的實例有時被稱為Spring的上下文,在通常的J2EE應用中,都應該考慮ApplicationContext接口,只有在J2EE應用非常關注內存的情況下,才考慮使用BeanFactory

3、Spring以bean方式管理組件,J2EE的全部組件都被當做bean來管理,Spring中的組件可以是Java對象或者Java組件;

4、在Spring整個應用中,各層的對象都處在Spring的管理下,這些對象以Bean的方式存在,Spring負責創建bean,並且管理其生命周期,bean在Spring容器中運行,無需感受Spring容器的存在,一樣可以運行,接受Spring的依賴注入,包括bean的屬性注入,合作者注入,依賴關系注入等

  注:Spring上下文(ApplicationContext)是產生bean的工廠,bean是工廠產生的實例,產生bean的實例時,需要知道bean的實現類,bean實例的使用者(即調用程序)面向的是接口,無需關心bean實例的實現類,Spring工廠(ApplicationContext)負責維護bean實例的實例化,使用者無需關心實例化。


 BeanFactory接口:

  BeanFactroy是一個Spring容器,用於創建,配置,管理bean,bean之間的依賴關系也有BeanFactory負責維護;

  BeanFactory對bean的實例化過程,無須bean的調用者關心,調用者只需要通過getBean()方法獲得指定bean的引用;

 創建BeanFactory的實例時,必須提供bean的詳細配置信息,bean的詳細信息通過XML文件描述,創建BeanFactory實例時,需要提供XML文件作為參數


 Bean生命周期:

下圖描述了 Bean 的生命周期。它是由 IoC 容器控制。IoC 容器定義 Bean 操作的規則,即 Bean 的定義(BeanDefinition)。Bean 的定義包含了 BeanFactory 在創建 Bean 實例時需要的所有信息。BeanFactory 首先通過構造函數創建一個 Bean 實例,之后它會執行 Bean 實例的一系列之前初始化動作,初始化結束 Bean 將進入准備就緒(ready)狀態,這時應用程序就可以獲取這些 Bean 實例了。最后,當你銷毀單例(Singleton)Bean 時,它會調用相應的銷毀方法,結束 Bean 實例的生命周期。

原理圖:

詳細步驟:

1、實例化(當程序加載applicationContext.xml文件),把bean(前提是scope=singleton)實例化到內存。

2、調用該Bean的setXxx()方法,設置屬性。

3、如果實現了bean名字關注接口(BeanNameAware),則可以通過setBeanName獲取id號。

4、如果實現了bean工廠關注接口(BeanFactoryAware),則可以獲取BeanFactory。

5、如果實現了ApplicationContextAware接口,則可以獲得ApplicationContext。

6、如果bean和一個后置處理器關聯,則會自動去調用postProcessBeforeInitialization()方法。

7、如果實現InitializingBean接口,則會調用afterPropertiesSet方法。

8、如果配置<bean init-method=”init” /> 則可以在bean自定義初始化方法。

9、如果bean和一個后置處理器關聯,則會自動去調用postProcessAfterInitialization()方法。

10、使用bean。

11、容器關閉。

12、可以通過實現DisposableBean接口來調用destory()方法。

13、可以在<bean destory-method=”fun1”/> 調用自定義的銷毀方法。

 


 

Spring配置文件:

<?xml version="1.0" encoding="utf-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="  
            http://www.springframework.org/schema/beans   
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://www.springframework.org/schema/aop   
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
            http://www.springframework.org/schema/tx   
            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
    <!-- 在容器文件中配置bean(service/dao/domain/action/數據源) -->  
    <bean id="personService" init-method="init" destroy-method="myDestory" class="com.pc.beanlife.PersonService">  
        <!-- 這里注入屬性,前提是有setName才能成功 -->  
        <property name="name" value="zs" />  
    </bean>  
    <!-- 配置后置處理器(類似filter) -->  
    <bean id="myBeanPostProcesseor" class="com.pc.beanlife.MyBeanPostProcesseor" />  
</beans>  

Bean類文件:

public class PersonService implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{  
    private String name;  
       
    public PersonService() {  
        System.out.println("無參構造方法被調用");  
    }  
       
    public PersonService(String name) {  
        System.out.println("有參構造方法被調用");  
    }  
       
    public void printOk(){  
        System.out.println(name + " is Ok");  
    }  
   
    public String getName() {  
        return name;  
    }  
   
    public void setName(String name) {  
        System.out.println("調用set方法設置屬性");  
        this.name = name;  
    }  
   
    // 該方法可以給name表示正被實例化的Bean的id  
    @Override 
    public void setBeanName(String name) {  
        // TODO Auto-generated method stub  
        System.out.println("setBeanName 被調用,值是" + name);  
    }  
   
    // 該方法可以傳遞beanFactory  
    @Override 
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {  
        // TODO Auto-generated method stub  
        System.out.println("setBeanFactory " + beanFactory);  
           
    }  
   
    // 該方法可以設置上下文  
    @Override 
    public void setApplicationContext(ApplicationContext applicationContext)  
            throws BeansException {  
        // TODO Auto-generated method stub  
        System.out.println("setApplicationContext " + applicationContext);  
    }  
   
    // 該方法可以在InitializingBean使用  
    @Override 
    public void afterPropertiesSet() throws Exception {  
        // TODO Auto-generated method stub  
        System.out.println("afterPropertiesSet");  
    }  
       
    // 自定義的初始化方法  
    public void init() {  
        System.out.println("調用自定義的初始化方法");  
    }  
   
    // 可以在這關閉數據連接,socket,文件流,釋放資源等等。。。  
    @Override 
    public void destroy() throws Exception {  
        // TODO Auto-generated method stub  
        System.out.println("調用destroy()");  
    }  
       
    // 自定義我們的銷毀方法  
    public void myDestory() {  
        System.out.println("調用自定義的銷毀方法");  
    }  
}  

后置處理器文件:

 

public class MyBeanPostProcesseor implements BeanPostProcessor {  
    // 后置處理之后的過濾  
    @Override 
    public Object postProcessBeforeInitialization(Object bean, String beanName)  
            throws BeansException {  
        // TODO Auto-generated method stub  
        System.out.println("postProcessBeforeInitialization方法被調用");  
        return bean;  
    }  
   
    // 后置處理之前的過濾  
    @Override 
    public Object postProcessAfterInitialization(Object bean, String beanName)  
            throws BeansException {  
        // TODO Auto-generated method stub  
        System.out.println("postProcessAfterInitialization方法被調用");  
        return bean;  
    }  
}  

 

測試類:

public class Test {  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        // 通過ApplicationContext加載Bean  
        System.out.println("------------在ApplicationContext中Bean的生命周期------------");  
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/pc/beanlife/beans.xml");  
        // 獲取Bean  
        PersonService personService = (PersonService) applicationContext.getBean("personService");  
        personService.printOk();  
           
        // 通過BeanFactory加載Bean  
        System.out.println("------------在BeanFactory中Bean的生命周期------------");  
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("com/pc/beanlife/beans.xml"));  
        PersonService personService2 = (PersonService) beanFactory.getBean("personService");  
        personService2.printOk();  
    }  

日志文件:

------------在ApplicationContext中Bean的生命周期------------  
無參構造方法被調用  
調用set方法設置屬性  
setBeanName 被調用,值是personService  
setBeanFactory org.springframework.beans.factory.support.DefaultListableBeanFactory@1f8b81e3: defining beans [personService,myBeanPostProcesseor]; root of factory hierarchy  
setApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext@771c8a71: display name [org.springframework.context.support.ClassPathXmlApplicationContext@771c8a71]; startup date [Sat Feb 20 11:34:05 CST 2016]; root of context hierarchy  
postProcessBeforeInitialization方法被調用  
afterPropertiesSet  
調用自定義的初始化方法  
postProcessAfterInitialization方法被調用  
zs is Ok  
------------在BeanFactory中Bean的生命周期------------  
無參構造方法被調用  
調用set方法設置屬性  
setBeanName 被調用,值是personService  
setBeanFactory org.springframework.beans.factory.xml.XmlBeanFactory@6c4fc156: defining beans [personService,myBeanPostProcesseor]; root of factory hierarchy  
afterPropertiesSet  
調用自定義的初始化方法  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM