[TOC]html
Spring容器既Application或者WebApplication會在管理Bean的時候;爲了儘量的把本身內部的東西機制暴露出來給用戶使用,因此在Bean建立的過程當中加了不少機制,經過所謂的"處理器"Processor暴露出來,而後處理器都有本身的順序,咱們須要作的就是定義好處理器的邏輯,而後註冊到Sprinhg容器中,Spring就會調用了。下面就是Spring管理Bean的生命週期圖。java
下面這張圖描述的更爲詳細。web
對於上面圖看不懂不要着急由於你並不認識與生命週期相關的接口。Spring生命週期你能夠理解爲四個等級;每一個等級中都用有相應的接口,實現其中某個接口或者將實現類注入到Sprng容器,容器就會在相應的時機調用其方法。詳細信息可看下面的一個表格。spring
分類 | 接口 | 調用時間 |
---|---|---|
工廠後處理器接口 | BeanFactoryPostProcessor | 容器建立完畢,裝配Bean源後當即調用 |
容器後處理器接口 | InstantiationAwareBeanPostProcessor | 分別在調用構造以前,注入屬性以前,實例化完成時調用 |
容器後處理器接口 | BeanPostProcessor | 分別在Bean的初始化方法調用先後執行 |
Bean級後置處理器接口 | BeanNameAware | 注入屬性後調用 |
Bean級後置處理器接口 | BeanFactoryAware | 注入屬性後調用 |
Bean級後置處理器接口 | InitializingBean | 在類自己的初始化方法以前調用其方法(自己也是初始化方法) |
Bean級後置處理器接口 | DiposableBean | 在類自己的銷燬方法執行以前調用其方法(自己也是銷燬方法) |
Bean自己方法 | init方法 | 在注入屬性以後調用初始化方法 |
Bean自己方法 | destroy方法 | 在關閉容器的時候進行銷燬 |
本測試程序來自https://www.cnblogs.com/zrtqsk/p/3735273.html
我在這裏說一下測試程序是如何測試SpringBean
的生命週期的。首先將一個工廠後處理器 BeanFactoryPostProcessor
接口實現注入容器,再將容器後處理器InstantiationAwareBeanPostProcessor
和BeanPostProcessor
注入容器,又在自定義Person
實現了Bean級後處理器BeanNameAware
,BeanFactoryAware
,InitializingBean
和DiposableBean
接口的相關方法,最後就是在自定義的Person類中實現了其自己的init()
方法和destroy()
方法。springboot
public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { private String name; private String address; private int phone; private BeanFactory beanFactory; private String beanName; public Person() { System.out.println("【構造器】調用Person的構造器實例化"); } public String getName() { return name; } public void setName(String name) { System.out.println("【注入屬性】注入屬性name"); this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { System.out.println("【注入屬性】注入屬性address"); this.address = address; } public int getPhone() { return phone; } public void setPhone(int phone) { System.out.println("【注入屬性】注入屬性phone"); this.phone = phone; } @Override public String toString() { return "Person [address=" + address + ", name=" + name + ", phone=" + phone + "]"; } // 這是BeanFactoryAware接口方法 @Override public void setBeanFactory(BeanFactory arg0) throws BeansException { System.out .println("【BeanFactoryAware接口】調用BeanFactoryAware.setBeanFactory()"); this.beanFactory = arg0; } // 這是BeanNameAware接口方法 @Override public void setBeanName(String arg0) { System.out.println("【BeanNameAware接口】調用BeanNameAware.setBeanName()"); this.beanName = arg0; } // 這是InitializingBean接口方法 @Override public void afterPropertiesSet() throws Exception { System.out .println("【InitializingBean接口】調用InitializingBean.afterPropertiesSet()"); } // 這是DiposibleBean接口方法 @Override public void destroy() throws Exception { System.out.println("【DiposibleBean接口】調用DiposibleBean.destory()"); } // 經過<bean>的init-method屬性指定的初始化方法 public void myInit() { System.out.println("【init-method】調用<bean>的init-method屬性指定的初始化方法"); } // 經過<bean>的destroy-method屬性指定的初始化方法 public void myDestory() { System.out.println("【destroy-method】調用<bean>的destroy-method屬性指定的初始化方法"); } }
public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { super(); System.out.println("這是BeanPostProcessor實現類構造器!!"); // TODO Auto-generated constructor stub } @Override public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException { System.out .println("BeanPostProcessor接口方法postProcessAfterInitialization對屬性進行更改!"); return arg0; } @Override public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException { System.out .println("BeanPostProcessor接口方法postProcessBeforeInitialization對屬性進行更改!"); return arg0; } }
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { super(); System.out .println("這是InstantiationAwareBeanPostProcessorAdapter實現類構造器!!"); } // 接口方法、實例化Bean以前調用 @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { System.out .println("InstantiationAwareBeanPostProcessor調用postProcessBeforeInstantiation方法"); return null; } // 接口方法、實例化Bean以後調用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out .println("InstantiationAwareBeanPostProcessor調用postProcessAfterInitialization方法"); return bean; } // 接口方法、設置某個屬性時調用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out .println("InstantiationAwareBeanPostProcessor調用postProcessPropertyValues方法"); return pvs; } }
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public MyBeanFactoryPostProcessor() { super(); System.out.println("這是BeanFactoryPostProcessor實現類構造器!!"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException { System.out .println("BeanFactoryPostProcessor調用postProcessBeanFactory方法"); BeanDefinition bd = arg0.getBeanDefinition("person"); bd.getPropertyValues().addPropertyValue("phone", "110"); } }
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="beanPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanPostProcessor"> </bean> <bean id="instantiationAwareBeanPostProcessor" class="com.jimisun.learnspringboot.web.MyInstantiationAwareBeanPostProcessor"> </bean> <bean id="beanFactoryPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanFactoryPostProcessor"> </bean> <bean id="person" class="com.jimisun.learnspringboot.web.Person" init-method="myInit" destroy-method="myDestory" scope="singleton" p:name="張三" p:address="廣州" p:phone="15900000000"/> </beans>
public class Main { public static void main(String[] args) { System.out.println("如今開始初始化容器"); ApplicationContext factory = new ClassPathXmlApplicationContext("bens.xml"); System.out.println("容器初始化成功"); //獲得Preson,並使用 Person person = factory.getBean("person",Person.class); System.out.println(person); System.out.println("如今開始關閉容器!"); ((ClassPathXmlApplicationContext)factory).registerShutdownHook(); } }
LOGGER測試:如今開始初始化容器 【工廠構造】這是BeanFactoryPostProcessor實現類構造器!! 【工廠方法】BeanFactoryPostProcessor調用postProcessBeanFactory方法 【容器構造】這是BeanPostProcessor實現類構造器!! 【容器構造】這是InstantiationAwareBeanPostProcessorAdapter實現類構造器!! 【容器方法】InstantiationAwareBeanPostProcessor調用postProcessBeforeInstantiation方法 【類構造】調用Person的構造器實例化 【容器方法】InstantiationAwareBeanPostProcessor調用postProcessPropertyValues方法 【類注入屬性】注入屬性address 【類注入屬性】注入屬性name 【類注入屬性】注入屬性phone 【Bean方法:BeanNameAware接口】調用BeanNameAware.setBeanName() 【Bean方法:BeanFactoryAware接口】調用BeanFactoryAware.setBeanFactory() 【容器方法】BeanPostProcessor接口方法postProcessBeforeInitialization對屬性進行更改! 【Bean方法:InitializingBean接口】調用InitializingBean.afterPropertiesSet() 【自身方法:init-method】調用<bean>的init-method屬性指定的初始化方法 【容器方法】BeanPostProcessor接口方法postProcessAfterInitialization對屬性進行更改! 【容器方法】InstantiationAwareBeanPostProcessor調用postProcessAfterInitialization方法 LOGGER測試:容器初始化成功 Person [address=廣州, name=張三, phone=110] LOGGER測試:如今開始關閉容器! 【Bean級別:DiposibleBean接口】調用DiposibleBean.destory() 【自身方法:destroy-method】調用<bean>的destroy-method屬性指定的初始化方法
將Demo代碼的執行結果與上述表中的執行時機進行對比,看看執行時機是否正確,框架
理解透徹Spring Bean的生命週期對開發中能夠解決比較棘手的問題,對於深刻學習Spring Framework框架這是必需要掌握的知識,因此能夠多看兩遍。ide
該教程所屬Java工程師之Spring Framework深度剖析專欄,本系列相關博文目錄 Java工程師之Spring Framework深度剖析專欄post
原文出處:https://www.cnblogs.com/jimisun/p/10098467.html學習