Spring提供了一些接口來提供一些方法,體現了bean對象在Spring容器中的生命週期
具體的過程能夠體現爲:spring
讀取權限類名->構建一個類對象->用這個類對象經過無參構造器newInstance()構建對象
↓
調用set方法注入依賴
↓
若是這個Bean已經實現了BeanNameAware接口
調用它實現的setBeanName(String name)方法
此處傳遞的就是Spring配置文件中Bean的name值
↓
若是這個Bean已經實現了BeanFactoryAware接口
容器會調用它實現的setBeanFactory方法
該方法接收的參數就是當前容器自己(能夠用這個方式來獲取其它Bean)
↓
若是這個Bean已經實現了ApplicationContextAware接口
容器會調用setApplicationContext方法,該步和第四步相似
↓
若是有類實現了BeanPostProcessor接口而且注入到容器中
那麼會執行該類中重寫的postProcessBeforeInitialization(Object bean, String beanName)
這個方法在本身定義的init-method以前調用
↓
執行本身在xml配置文件中注入對象定義的init-method方法
↓
若是有類實現了BeanPostProcessor接口而且注入到容器中
那麼會執行該類中重寫的postProcessAfterInitialization(Object bean, String beanName)
這個方法在本身定義的init-method以後調用
↓
當Bean再也不須要時,會通過清理階段
若是Bean實現了DisposableBean這個接口
會調用那個其實現的destroy()方法
↓
最後,若是這個Bean的Spring配置中配置了destroy-method屬性
會自動調用其配置的銷燬方法ide
設計一個類來測試bean對象的生命週期post
/*這裏面測試的是spring容器中bean對象完整的生命週期*/ public class Life implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,DisposableBean{ private String name; public String getName() { return name; } //一、容器建立該Bean的對象 public Life() { System.out.println("第一步,建立對象"); } //二、容器給這個Bean對象注入依賴 public void setName(String name) { System.out.println("第二步,依賴注入"); this.name = name; } //三、若是這個Bean已經實現了BeanNameAware接口,容器會調用它實現的setBeanName(String)方法,此處傳遞的就是Spring配置文件中Bean的id值 @Override public void setBeanName(String name) { System.out.println("第三步,調用setBeanName方法,由於bean類實現了BeanNameAware"); } //四、若是這個Bean已經實現了BeanFactoryAware接口,容器會調用它實現的setBeanFactory方法 //該方法接收的參數就是當前容器自己(能夠用這個方式來獲取其它Bean) @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("第四步,調用setBeanFactory方法,由於bean類實現了BeanFactoryAware"); } //五、若是這個Bean已經實現了ApplicationContextAware接口,容器會調用setApplicationContext方法,該步和第四步相似,ApplicationContext是BeanFactory的子接口,有更多的實現方法 @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { System.out.println("第五步,調用setApplicationContext方法,由於bean類實現了ApplicationContextAware"); } //九、當Bean再也不須要時,會通過清理階段,若是Bean實現了DisposableBean這個接口,會調用那個其實現的destroy()方法; @Override public void destroy() throws Exception { System.out.println("第九步,調用destroy方法,由於bean類實現了ApplicationContextAware"); } /** *注意下面的兩個方法是自定義的初始化和銷燬對象方法 *須要在注入對象的時候指定init-method="..",destroy-method="..." *注意方法的執行順序 *init-method在各個初始化方法執行以後才執行 *destroy-method在最後執行 */ //七、若是Bean在Spring配置文件中配置了init-method屬性則會自動調用其配置的初始化方法 //init-method="myInit" public void myInit(){ System.out.println("第七步,調用myInit方法,由於bean在xml中的配置裏面使用了init-method屬性來指定初始化方法"); } //十、最後,若是這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷燬方法 public void myDestroy(){ System.out.println("第十步,調用myDestroy方法,由於bean在xml中的配置裏面使用了destroy-method屬性來指定初始化方法"); } }
再寫一個類用來實現BeanPostProcessor接口測試
/*注意:須要把這個類註冊到spring的容器中,才能生效*/ public class MyBeanPostProcessor implements BeanPostProcessor{ //這個方法在本身定義的init-method以前調用 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("第六步,調用postProcessBeforeInitialization方法,由於spring容器中註冊了BeanPostProcessor接口的實現類"); return bean; } //這個方法在本身定義的init-method以後調用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("第八步,調用postProcessAfterInitialization方法,由於spring容器中註冊了BeanPostProcessor接口的實現類"); return bean; } }
咱們在配置文件中進行一個配置this
<bean class="com.briup.ioc.life.MyBeanPostProcessor"></bean> <bean name="life" class="Life" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="張三"></property> </bean>
以上是完整的生命週期,下面來講的是非完整的生命週期,通常來講在開發的時候沒有必要每次都讓一個對象都具備完整生命週期的方法spa
/*這裏面測試的是spring容器中bean對象普通的聲明週期*/ /*Bean中不實現spring提供的任何接口,以後項目大多數Bean是這種狀況*/ public class LifeBean{ private String name; public LifeBean(){ System.out.println("LifeBean() 構造器"); } public String getName() { return name; } public void setName(String name) { System.out.println("setName() 方法"); this.name = name; } public void init(){ System.out.println("init方法執行"); } public void destory(){ System.out.println("destory方法執行"); } }
生命周器對於單例對象和非單例對象來講,非單例對象在建立後會脫離容器的控制
單例管理的對象:
1.默認狀況下,spring在讀取xml文件的時候,就會建立對象
2.進行依賴注入,若是有依賴的話
3.會去調用init-method=".."屬性值中所指定的方法,若是有該配置的話
4.Bean對象能夠被正常使用
5.對象在被銷燬的時候,會調用destroy-method="..."屬性值中所指定的方法,若是有該配置的話設計
注意1:調用container.destroy()方法會銷燬單例對象
注意2:lazy-init="true",可讓這個Bean對象在第一次被訪問的時候建立,而不是讀取xml文件就被建立
注意3:由於是單例,因此該對象只會被建立一次code
非單例管理的對象:
1.使用這個對象的時候,spring容器會建立這個對象
2.進行依賴注入,若是有依賴的話
3.會去調用init-method=".."屬性值中所指定的方法,若是有該配置的話
4.Bean對象能夠被正常使用xml
注意1:spring容器不會銷燬非單例對象
注意2:由於是非單例,因此每次使用都會建立一個新的Bean對象
非單例也是當獲取對象的時候再加載,不會受到Spring容器的管理對象