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被調用