spring心得3--bean的生命週期結合案例詳細講解@普通期圖解與uml圖解一併分析
1.繼上一篇部落格續將,bean生命週期理論概括
bean被載入到容器中時,他的生命週期就開始了。bean工廠在一個bean可以使用前完成很多工作:
1).容器尋找bean的定義資訊並例項化。
2).使用依賴注入,spring按bean定義資訊配置bean的所有屬性。
3).若bean實現了BeanNameAware介面,工廠呼叫Bean的setBeanName()方法傳遞bean的ID。
4).若bean實現了BeanFactoryAware介面,工廠呼叫setBeanFactory()方法傳入工廠自身。
5).若BeanPostProcessor和bean關聯,則它們的 postProcessBeforeInitialization()方法被呼叫。
6).若bean指定了ini-method方法、,它將被呼叫。
7).最後,若有BeanPostProcessor和bean關聯,則它們的postProcessAfterInitialization()方法被呼叫。
將bean從工廠中刪掉有兩種方法:
1).若bean實現了DisposableBean介面,distroy()方法被呼叫。
2).如果指定了定製的銷燬方法,就呼叫這個方法。
bean在應用上下文中的生命週期和在bean工廠的生命週期唯一不同的是:若bean實現了ApplicationContextAware()介面,setApplicationContext()方法會被呼叫。
2.案例加註釋詳細剖解bean的生命週期
測試類的程式碼
package www.csdn.spring.test;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import www.csdn.spring.dao.impl.HelloDaoImpl;
publicclass CycleTest {
@Test
publicvoid cycleTest() {
/**
* bean的生命週期 bean被載入到容器中時,他的生命週期就開始了。bean工廠在一個bean可以使用前完成很多工作:
*
* 1.容器尋找bean的定義資訊並例項化。使用bean工廠或擴充套件的bean工廠context上下文來說明該知識點
* ClassPathXmlApplicationContext context = new
* ClassPathXmlApplicationContext("spring-dao.xml");
*
* 2.使用依賴注入,spring按bean定義資訊配置bean的所有屬性。
* 通過在dao中宣告content屬性並建立setter方法以及spring-dao.xml配置這樣的資訊來說明: <property
* name="content" value="hello!楊凱!"/>
*
* 3.若bean實現了BeanNameAware介面,工廠呼叫Bean的setBeanName ()方法傳遞bean的ID。
* 通過dao中的繼承改介面,並實現改介面的相應方法public void setBeanName(String
* beanId)來說明知識點;重點程式碼在dao中
*
* 4.若bean實現了BeanFactoryAware介面,工廠呼叫setBeanFactory()方法傳入工廠自身。
* 通過dao中的繼承改介面,並實現改介面的相應方法public void setBeanFactory(BeanFactory
* factory) throws BeansException 來說明該知識點,重點程式碼在dao中。
*
* 5.若BeanPostProcessor和bean關聯,則它們的
* postProcessBeforeInitialization()方法被呼叫。
* 改類是個全域性控局類,只要在一個bean的配置檔案和相應bean類中實現了該介面並重寫了該介面的方法,在整個專案的bean類中都會起作用
* 所以這裡為了更好說明問題,新建一個BeanPostProcessorImpl類去實現BeanPostProcessor介面
*
* 6.若bean指定了ini-method、destroy-method方法,它將被呼叫。
* 通過在bean的指定spring配置檔案中配置屬性init-method="init" destroy-method="destroy"
* 尤其是使destroy-method方法起作用的使用,一定要在測試類中關閉bean工廠物件context.close();
*
* 7.最後,若有BeanPostProcessor和bean關聯,則它們的postProcessAfterInitialization()
* 方法被呼叫。、同第五個before一樣
*/
/*// 使用上下文context模擬的bean的生命週期:使用ClassPathXmlApplicationContext物件接收
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("spring-dao.xml");
context.getBean("helloDaoImpl",HelloDaoImpl.class).sayHello();
// 執行關閉,以下兩個方法都可以使destory-method的方法的執行
context.destroy();
// context.close();
*/
//使用ApplicationContext物件接收,呼叫getBean與上面的方法一樣,不同的是銷燬與關閉的方法需要強轉為AbstractApplicationContext型別的
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
context.getBean("helloDaoImpl",HelloDaoImpl.class).sayHello();
// 執行關閉,以下兩個方法都可以使destory-method的方法的執行
//((AbstractApplicationContext) context).destroy();
((ConfigurableApplicationContext) context).close();
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=--=-=-=-=-=-==");
/**
* 除了應用上下文提供的附加功能外,應用上下文與bean工廠的另一個重要區別是關於單例bean 如何被載入。
* bean工廠延遲載入所有bean,直到getBean() 方法被呼叫。應用上下文會在啟動後預載入所有單例bean.
* 這樣可確保應用不需要等待他們被建立。
* 使用bean工廠模擬的bean的生命週期:
*/
ConfigurableBeanFactory cbf = new XmlBeanFactory(new ClassPathResource("spring-dao.xml"));
/*bean工廠呼叫BeanPostProcessor類的方法也與上下文物件不一樣,上下文物件直接在配置檔案使用bean標籤指明即可,
* 而在bean工廠中需要下面一個方法去呼叫該類
*/
//cbf.addBeanPostProcessor(new BeanPostProcessorImpl());
//這種方法也可以呼叫BeanPostProcessor,與上面結果一樣
cbf.addBeanPostProcessor(cbf.getBean("beanPostProcessorImpl",BeanPostProcessorImpl.class));
//只有使用getBean方法後所有的初始化資訊才會執行
cbf.getBean("helloDaoImpl",HelloDaoImpl.class);
//使用下面的方法銷燬所有的單例物件
cbf.destroySingletons();
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- spring容器就是負責建立、管理、維護Bean 並且能夠依賴注入到相應元件上 -->
<bean id="helloDaoImpl" class="www.csdn.spring.dao.impl.HelloDaoImpl"
scope="singleton" lazy-init="false" init-method="init" destroy-method="destroy">
<!-- 通過set方法注入 -->
<property name="content" value="hello!楊凱!" />
</bean>
<!-- spring-service.xml引用的改配置檔案,所以在前者中加入了lazy-init="false",這裡可以不寫也會起作用;
lazy-init屬性的意思是:是否延遲載入,就是一建立 spring容器就去例項化對應容器物件,即執行改物件的構造器,而不是在使用的時候才去載入
lazy-init="false" ,預設的值為default,但是default=false -->
<!-- BeanPostProcessor與當前的bean都進行關聯 -->
<bean id="beanPostProcessorImpl" class="www.csdn.spring.test.BeanPostProcessorImpl" />
</beans>
bean例項程式碼(這裡把dao做bean講解)
package www.csdn.spring.dao.impl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import www.csdn.spring.dao.HelloDao;
public class HelloDaoImpl implements HelloDao, BeanNameAware, BeanFactoryAware,
ApplicationContextAware,InitializingBean {
private String content;
public void setContent(String content) {
System.out.println("say:setter注入的內容是:" + content);
this.content = content;
}
public HelloDaoImpl() {
System.out.println("HelloDaoImpl例項化。。。。");
}
@Override
public void sayHello() {
System.out.println("say:hello world!");
}
public void init() {
System.out.println("----init方法執行了----");
}
public void destroy() {
System.out.println("=====destory方法執行了=====");
}
@Override
public void setBeanName(String beanId) {
/*
* 這裡只能檢視beanId,即使修改也只在改方法內生效,並沒有傳出去,所以在其他方法中使用的beanId還是配置檔案中傳過來的id
* 而不是被修改過的id;並且這裡只能檢視id,不能使用bean工廠操作,也就是說不能使用傳過來的id去呼叫bean工廠來操作類
* 更不能使用修改後的id去呼叫bean工廠來操作類
*/
System.out.println("傳遞bean的ID為:"+beanId);
beanId = "hello";
System.out.println("修改後的bean的ID為:"+beanId);
}
@Override
public void setBeanFactory(BeanFactory factory) throws BeansException {
/*
* 這裡可以使用bean工廠執行bean類中的方法的前提是在配置中使用scope="singleton"
* lazy-init="default" 這兩個屬性才可以達到預期效果,否則控制檯根本不輸出內容
*/
System.out.println(factory.getClass()+"-----"+factory.getBean("helloDaoImpl"));
factory.getBean("helloDaoImpl",HelloDaoImpl.class).sayHello();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("--呼叫:" + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("----initializingBean介面的方法被呼叫了。。。。");
}
}
3.bean的生命週期狀態圖解
第一個圖中是使用上下文物件通過spring配置檔案來建立、管理、維護的狀態圖解,藍色字型是對比第二張圖的不同之處;第二張圖是bean工廠物件過spring配置檔案來建立、管理、維護的狀態圖解。
4.bean生命週期的UML狀態圖解
上下文物件
Bean工廠物件
注:bean在ApplicationContext中的生命週期與BeanFactory中唯一的不同是若實現了ApplicationContextAware()介面則會呼叫setApplicationContext()方法,執行順序是在setBeanFactory()方法之後,預初始化方法之前。
相關文章
- 圖解vue生命週期圖解Vue
- vue生命週期詳解Vue
- React生命週期詳解React
- 詳解vue生命週期Vue
- Service生命週期詳解
- 詳解Spring中Bean的作用域與生命週期SpringBean
- Vue的生命週期的詳解Vue
- 詳解Vue生命週期【上】Vue
- React 元件生命週期詳解React元件
- React元件生命週期詳解React元件
- Java類的生命週期詳解Java
- 生命週期詳細解讀(含部分原始碼)原始碼
- 圖解ES6中的React生命週期圖解React
- 詳解 Vue 生命週期實現Vue
- Android Activity生命週期詳解Android
- Android View的生命週期詳解AndroidView
- React原始碼分析3—React生命週期詳解React原始碼
- 圖解React的生命週期及執行順序圖解React
- Java Servlet詳解(體系結構+註解配置+生命週期)JavaServlet
- 多執行緒-執行緒生命週期圖解執行緒圖解
- Activity的生命週期和啟動模式詳解模式
- Servlet簡介及其生命週期詳解Servlet
- 《Oracle Streams技術引航》-全生命週期式講解-手操-圖文-可下載Oracle
- Java面試必考題之執行緒的生命週期,結合原始碼,透徹講解!Java面試執行緒原始碼
- 高德地圖之地圖的生命週期地圖
- UML類圖詳解
- Android生命週期元件Lifecycle使用詳解Android元件
- Vue生命週期詳解+對應程式碼解析Vue
- 大廠高頻面試題Spring Bean生命週期最詳解面試題SpringBean
- 附例項!圖解React的生命週期及執行順序圖解React
- Android Activity的生命週期和啟動模式詳解Android模式
- android Fragments詳解六:處理fragement的生命週期AndroidFragment
- Spring Boot 啟動原始碼解析結合Spring Bean生命週期分析Spring Boot原始碼Bean
- Django(35)Django請求生命週期分析(超詳細)Django
- UML 用例圖詳解
- UML類圖與類的關係詳解
- spring生命週期Spring
- View生命週期與Activity生命週期的關係View