Spring Bean生命週期, ApplicationContext 和BeanFactory

輸入圖片說明

ApplicationContext容器中,Bean的生命週期流程如上圖所示,流程大體以下:spring

1.首先容器啓動後,會對scope爲singleton且非懶加載的bean進行實例化, 2.按照Bean定義信息配置信息,注入全部的屬性, 3.若是Bean實現了BeanNameAware接口,會回調該接口的setBeanName()方法,傳入該Bean的id,此時該Bean就得到了本身在配置文件中的id, 4.若是Bean實現了BeanFactoryAware接口,會回調該接口的setBeanFactory()方法,傳入該Bean的BeanFactory,這樣該Bean就得到了本身所在的BeanFactory, 5.若是Bean實現了ApplicationContextAware接口,會回調該接口的setApplicationContext()方法,傳入該Bean的ApplicationContext,這樣該Bean就得到了本身所在的ApplicationContext, 6.若是有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessBeforeInitialzation()方法, 7.若是Bean實現了InitializingBean接口,則會回調該接口的afterPropertiesSet()方法, 8.若是Bean配置了init-method方法,則會執行init-method配置的方法, 9.若是有Bean實現了BeanPostProcessor接口,則會回調該接口的postProcessAfterInitialization()方法, 10.通過流程9以後,就能夠正式使用該Bean了,對於scope爲singleton的Bean,Spring的ioc容器中會緩存一份該bean的實例,而對於scope爲prototype的Bean,每次被調用都會new一個新的對象,期生命週期就交給調用方管理了,再也不是Spring容器進行管理了 11.容器關閉後,若是Bean實現了DisposableBean接口,則會回調該接口的destroy()方法, 12.若是Bean配置了destroy-method方法,則會執行destroy-method配置的方法,至此,整個Bean的生命週期結束緩存

BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean五個接口,而且在applicationContext.xml文件中配置了該Bean的id爲person1,而且配置了init-method和destroy-method,爲該Bean配置了屬性name爲jack的值,而後定義了一個MyBeanPostProcessor方法,該方法實現了BeanPostProcessor接口,且在applicationContext.xml文件中配置了該方法的Bean,其代碼以下所示:app

<?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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.2.xsd">
                    
     <bean id="person1" destroy-method="myDestroy" 
            init-method="myInit" class="com.test.spring.life.Person">
        <property name="name">
            <value>jack</value>
        </property>
    </bean>
    
    <!-- 配置自定義的後置處理器 -->
     <bean id="postProcessor" class="com.pingan.spring.life.MyBeanPostProcessor" />
</beans>
public class Person implements BeanNameAware, BeanFactoryAware,
        ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;
    
    public Person() {
        System.out.println("PersonService類構造方法");
    }
    
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        System.out.println("set方法被調用");
    }

    //自定義的初始化函數
    public void myInit() {
        System.out.println("myInit被調用");
    }
    
    //自定義的銷燬方法
    public void myDestroy() {
        System.out.println("myDestroy被調用");
    }

    public void destroy() throws Exception {
        // TODO Auto-generated method stub
     System.out.println("destory被調用");
    }

    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("afterPropertiesSet被調用");
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        // TODO Auto-generated method stub
       System.out.println("setApplicationContext被調用");
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        // TODO Auto-generated method stub
         System.out.println("setBeanFactory被調用,beanFactory");
    }

    public void setBeanName(String beanName) {
        // TODO Auto-generated method stub
        System.out.println("setBeanName被調用,beanName:" + beanName);
    }
    
    public String toString() {
        return "name is :" + name;
    }
public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        // TODO Auto-generated method stub
        
        System.out.println("postProcessBeforeInitialization被調用");
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization被調用");
        return bean;
    }

}
public class AcPersonServiceTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        System.out.println("開始初始化容器");
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/test/spring/life/applicationContext.xml");
        
        System.out.println("xml加載完畢");
        Person person1 = (Person) ac.getBean("person1");
        System.out.println(person1);        
        System.out.println("關閉容器");
        ((ClassPathXmlApplicationContext)ac).close();
        
    }

}

啓動容器,能夠看到整個調用過程:函數

開始初始化容器
九月 25, 2016 10:44:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy
九月 25, 2016 10:44:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [com/test/spring/life/applicationContext.xml]
Person類構造方法
set方法被調用
setBeanName被調用,beanName:person1
setBeanFactory被調用,beanFactory
setApplicationContext被調用
postProcessBeforeInitialization被調用
afterPropertiesSet被調用
myInit被調用
postProcessAfterInitialization被調用
xml加載完畢
name is :jack
關閉容器
九月 25, 2016 10:44:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy
destory被調用
myDestroy被調用

BeanFactory Bean生命週期post

輸入圖片說明

BeanFactoty容器中, Bean的生命週期如上圖所示,與ApplicationContext相比,有以下幾點不一樣:this

1.BeanFactory容器中,不會調用ApplicationContextAware接口的setApplicationContext()方法, 2.BeanPostProcessor接口的postProcessBeforeInitialzation()方法和postProcessAfterInitialization()方法不會自動調用,必須本身經過代碼手動註冊 3.BeanFactory容器啓動的時候,不會去實例化全部Bean,包括全部scope爲singleton且非懶加載的Bean也是同樣,而是在調用的時候去實例化。prototype

咱們仍是使用前面定義好的Person類和MyBeanPostProcessor類,以及ApplicationContext.xml文件,main函數實現以下:code

public class BfPersonServiceTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("開始初始化容器");  
        ConfigurableBeanFactory bf = new XmlBeanFactory(new ClassPathResource("com/pingan/spring/life/applicationContext.xml"));
        System.out.println("xml加載完畢");      
        //beanFactory須要手動註冊beanPostProcessor類的方法
        bf.addBeanPostProcessor(new MyBeanPostProcessor());
        Person person1 = (Person) bf.getBean("person1");
            System.out.println(person1);
        System.out.println("關閉容器");
        bf.destroySingletons();
    }

}

啓動容器,咱們能夠看到整個調用流程:xml

開始初始化容器
九月 26, 2016 12:27:05 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [com/pingan/spring/life/applicationContext.xml]
xml加載完畢
PersonService類構造方法
set方法被調用
setBeanName被調用,beanName:person1
setBeanFactory被調用,beanFactory
postProcessBeforeInitialization被調用
afterPropertiesSet被調用
myInit被調用
postProcessAfterInitialization被調用
name is :jack
關閉容器
destory被調用
myDestroy被調用
相關文章
相關標籤/搜索