javascript
Spring源码深度解析,Spring源码以及Bean的生命周期(五)(附代码示例:)
五)Bean 的生命周期,創(chuàng)建---初始化---銷毀的過程
目錄
五)Bean 的生命周期,創(chuàng)建---初始化---銷毀的過程
一 ,? 指定初始化方法 init-method 方法?? ?
二 ,指定銷毀 destory-method 方法
三,實現(xiàn) InitializingBean 接口的 afterPropertiesSet()方法,當(dāng)beanFactory 創(chuàng)建好對象,且把bean所有屬性設(shè)置好之后,相當(dāng)于初始化方法。
實現(xiàn) DisposableBean 的destory(),方法 當(dāng)bean銷毀時,會把單例bean 進(jìn)行銷毀
四,? ?可以使用JSR250規(guī)則定義的(java規(guī)范)兩個注解來實現(xiàn),JDK自帶
五,Bean?的后置處理器,在?Bean?初始化之前調(diào)用進(jìn)行攔截,在?bean?初始化前后進(jìn)行一些處理工作,使用BeanPostProcessors 控制? Bean的生命周期。
實現(xiàn)? BeanPostProcessors兩個接口即可:
六 :項目Demo
一 ,? 指定初始化方法 init-method 方法
- 單實例 Bean,可以正常調(diào)用初始化和銷毀方法
- 多實例的?Bean,容器只負(fù)責(zé)初始化,但不會管理bean,容器關(guān)閉時不會調(diào)用銷毀方法
? ? 示例代碼:===》? ?項目 源碼? ====》? Cap8包:??xml 方式 指定
<!--創(chuàng)建Bike 類 bike 實例, 自定義初始化方法 init(),自定義銷毀方法 destory()--><bean id="bike" class="com.enjoy.Cap8.bean.Bike" init-method="init" destroy-method="destory"></bean>? ?注解實現(xiàn)===》項目 源碼? ====》? Cap8包:? ?(單實例模式下在容器創(chuàng)建之前實例化? Bean )? ? ?
//自定義初始化方法, 銷毀方法@Bean(initMethod = "init",destroyMethod = "destory")public Bike bike(){System.out.println("公交車到站了====》注冊到bean");return new Bike();}?
public class Bike {public Bike(){System.out.println("有一位乘客上車了=====>調(diào)類的構(gòu)造方法");}//自定義bean 初始化方法public void init(){System.out.println("車啟動了====》 bean初始化方法");}//自定義bean 銷毀方法public void destory(){System.out.println("車爆炸了====》bean銷毀方法,關(guān)閉容器");} }? 測試結(jié)果:
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);app.close();}?
注解實現(xiàn)===》項目 源碼? ====》? Cap8包(多實例,容器在創(chuàng)建之前 不會去實例化 Bean ,只有當(dāng) getBean()? 的時候才會去 創(chuàng)建實例 )? ?
//自定義初始化方法, 銷毀方法,多實例模式下@Scope("prototype")@Bean(initMethod = "init",destroyMethod = "destory")public Bike bike(){System.out.println("公交車到站了====》注冊到bean");return new Bike();}? Bike? 與上面一致? ?測試 :
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);System.out.println("容器創(chuàng)建完成");//app.getBean("bike");app.close();}? ?當(dāng)我沒有去getBean 的時候,? Bean 并沒有實例化
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);System.out.println("容器創(chuàng)建完成");app.getBean("bike");app.close();}? 結(jié)果顯而易見,? 在容器創(chuàng)建完成之后getBean()? 才會去 創(chuàng)建 Bean? 的實例 ,并且沒有調(diào)用銷毀方法
?
實現(xiàn)原理: 源碼跟蹤??
? ?
二 ,指定銷毀 destory-method 方法
? ? ? ? ? ? ? 示例代碼:見? ?5.1 代碼? ?====》項目源碼? Cap8;
三,實現(xiàn) InitializingBean 接口的 afterPropertiesSet()方法,當(dāng)beanFactory 創(chuàng)建好對象,且把bean所有屬性設(shè)置好之后,相當(dāng)于初始化方法。
實現(xiàn) DisposableBean 的destory(),方法 當(dāng)bean銷毀時,會把單例bean 進(jìn)行銷毀
示例源碼:?====》項目源碼? Cap8;
// 將 類注解為注解,讓容器掃描注入bean @Component public class Volkswagen implements InitializingBean, DisposableBean {public Volkswagen(){System.out.println("構(gòu)造方法, 大眾cc,買到手");}//實現(xiàn) DisposableBean 接口, destroy 銷毀方法@Overridepublic void destroy() throws Exception {System.out.println("大眾cc,沒了。。===》 容器銷毀");}//實現(xiàn) InitializingBean 接口, afterPropertiesSet() 初始化方法@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("大眾cc,最愛。。===》 bean初始化");} }在配置類 增加掃描注解 將 該包下面的掃描到容器中?
@Configuration //掃描包下所有組件,并注入bean 到容器 @ComponentScan("com.enjoy.Cap8.bean") public class Cap8MainConfigOfLifeCycle {//自定義初始化方法, 銷毀方法,多實例模式下@Scope("prototype")@Bean(initMethod = "init",destroyMethod = "destory")public Bike bike(){System.out.println("公交車到站了====》注冊到bean");return new Bike();}}測試:
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);System.out.println("容器創(chuàng)建完成");//System.out.println(app.getBean("bike"));System.out.println(app.getBean("volkswagen"));app.close();}四,? ?可以使用JSR250規(guī)則定義的(java規(guī)范)兩個注解來實現(xiàn),JDK自帶
- ? ? ? ? ? @PostConstruct : 在Bean 創(chuàng)建完成,且shu屬于賦值完成后進(jìn)行初始化,屬于JDK規(guī)范的注解
- ? ? ? ? ? @PreDestroy? ?:? ? 在Bean? 將被移除之前進(jìn)行通知,在容器銷毀之前進(jìn)行清理工作
示例源碼:?====》項目源碼? Cap8;
@Component public class Benz {public Benz(){System.out.println("構(gòu)造方法,買了一輛奔馳");}//使用JSR250規(guī)則定義 JDK 自帶注解 初始化 bean@PostConstructpublic void init(){System.out.println("奔馳漏油了 ====》初始bean");}//使用JSR250規(guī)則定義 JDK 自帶注解 容器銷毀@PreDestroypublic void destroy(){System.out.println("奔馳爆炸了 ====》容器銷毀");} }在配置類 增加掃描注解 將 該包下面的掃描到容器中?
@Configuration //掃描包下所有組件,并注入bean 到容器 @ComponentScan("com.enjoy.Cap8.bean") public class Cap8MainConfigOfLifeCycle {//自定義初始化方法, 銷毀方法,多實例模式下@Scope("prototype")@Bean(initMethod = "init",destroyMethod = "destory")public Bike bike(){System.out.println("公交車到站了====》注冊到bean");return new Bike();}}測試?
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);System.out.println("容器創(chuàng)建完成");//System.out.println(app.getBean("bike"));//System.out.println(app.getBean("volkswagen"));System.out.println(app.getBean("benz"));app.close();}五,Bean?的后置處理器,在?Bean?初始化之前調(diào)用進(jìn)行攔截,在?bean?初始化前后進(jìn)行一些處理工作,使用BeanPostProcessors 控制? Bean的生命周期。
實現(xiàn)? BeanPostProcessors兩個接口即可:
- ?postProcessBeforelnitialization()? ? 在Bean? 初始化之前? ? ? ?進(jìn)行攔截 增強(qiáng)
- ?postProcessAfterInitalization()? ? ? ? 在Bean? 初始化之后? ? ?? 進(jìn)行攔截 增強(qiáng)
Spring 底層對?BeanPostProcessor?的使用,包括 bean 的賦值,注入其他組件,生命周期注解功能等。 如:
- ApplicationContextAwareProcesspor? 接口? ? 這個后置處理器其實就是判斷我們的 bean 有沒有實現(xiàn)? ApplicationContextAware 這個接口? ,并處理相應(yīng)的邏輯,
- BeanValidationPostProcess 接口? 數(shù)據(jù)校驗
- InitDestroyAnnotationBeanPostProcessor 接口? 此處理器? 是用來處理? ?上述 5.4@PostConstruct? @PreDestroy? ?讓 容器 找到 init 方法 和? destroy 方法?
?
? ? 示例源碼:?====》項目源碼? Cap8;
?實現(xiàn)? BeanPostProcessors 接口, 里面的兩個方法
@Component public class Bmw implements BeanPostProcessor {/**Aop 在初始化bean 攔截 進(jìn)行增強(qiáng) 做一些操作,如 任何bean 初始化回調(diào)或自定義初始化方法之前,*將此BeanPostProcessor應(yīng)用于給定的新bean實例 bean已經(jīng)填充了屬性值。 返回的bean實例可能是原始實例的包裝器**/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessBeforeInitialization=====>"+bean+"===>"+beanName);return bean;}/**Aop 在初始化bean 攔截 進(jìn)行增強(qiáng) 做一些操作,如 一般的Aop 事務(wù) 在事件之后 commit,*在bean初始完后 攔截 增強(qiáng) 對于FactoryBean,將為FactoryBean 實例和FactoryBean創(chuàng)建的對象調(diào)用此回調(diào)。 * 處理器可以通過相應(yīng)的檢查來決定是應(yīng)用于FactoryBean還是應(yīng)用于創(chuàng)建的對象。 與所有其他BeanPostProcessor回調(diào)相比**/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization=====>"+bean+"===>"+beanName);return bean;} }?
配置類 ; 為了便于觀察? ?當(dāng)前 只是 掃描到? benz 這個類??
@Configuration //掃描包下所有組件,并注入bean 到容器 @ComponentScan("com.enjoy.Cap8.bean") public class Cap8MainConfigOfLifeCycle {//自定義初始化方法, 銷毀方法,多實例模式下//@Scope("prototype")//@Bean(initMethod = "init",destroyMethod = "destory")public Bike bike(){System.out.println("公交車到站了====》注冊到bean");return new Bike();}}測試:
@Testpublic static void main(String[] args){//創(chuàng)建上下文對象AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfigOfLifeCycle.class);System.out.println("容器創(chuàng)建完成");//System.out.println(app.getBean("bike"));//System.out.println(app.getBean("volkswagen"));System.out.println(app.getBean("benz"));app.close();}觀察結(jié)果
? ??
六 :項目Demo
Spring源碼深度解析,(附代碼示例 碼云地址: https://gitee.com/Crazycw/SpringCode.git)
參考資料:??https://docs.spring.io/spring/docs/4.3.18.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/
請看下篇: Spring源碼深度解析,初始Spring源碼(六)(附代碼示例:)
?
總結(jié)
以上是生活随笔為你收集整理的Spring源码深度解析,Spring源码以及Bean的生命周期(五)(附代码示例:)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言c20,C20、C30、C50混凝
- 下一篇: Word 写文档时使域背景为灰色以便清晰