Bean 的生命周期 之 後處理Bean
這裡先把Bean 的生命周期總結一下,然後引出後處理Bean
首先,Bean 的生命周期總共有11步:
1.instantiate bean對象實例化
2.populate properties 封裝屬性
3.如果Bean實現BeanNameAware 執行 setBeanName
4.如果Bean實現BeanFactoryAware 或者 ApplicationContextAware 設置工廠 setBeanFactory 或者上下文對象 setApplicationContext
5.如果存在類實現 BeanPostProcessor(後處理Bean),執行postProcessBeforeInitialization
6.如果Bean實現InitializingBean 執行 afterPropertiesSet
7.調用<bean init-method="init"> 指定初始化方法 init
8.如果存在類實現 BeanPostProcessor(處理Bean),執行postProcessAfterInitialization
9.執行業務處理
10.如果Bean實現 DisposableBean 執行 destroy
11.調用<bean destroy-method="customerDestroy"> 指定銷毀方法 customerDestroy
通過測試的話,我們能很容易的驗證這11個步驟,但是這11個步驟裡面最重要的還是第5步和第8步
然而,第五步是在Bean初始化之前執行,我不知道這一步有什麼用(請大神指點)
但是我知道,在第8步裡面,可以添加一些自己的代碼,就可以實現對方法的增強!也就是我們執行業務(第九步)之前就可以調用。然後對指定的方法進行增強
大家一定要注意,第五步和第八步室友前提的存在類實現 BeanPostProcessor這裡用戶色標出希望大家注意!!!!!!!
也就是我們自己要定義一個後處理器,並實現其中的兩個方法!如下代碼:
1 public class MyBeanPostProcessor implements BeanPostProcessor{
2 /**
3 * bean:實例對象
4 * beanName:在配置文件中配置的類的標識.
5 */
6 public Object postProcessBeforeInitialization(Object bean, String beanName)
7 throws BeansException {
8 System.out.println("第五步:初始化之前執行...");
9 return bean;
10 }
11
12 public Object postProcessAfterInitialization(final Object bean, String beanName)
13 throws BeansException {
14 System.out.println("第八步:初始化後執行...");
15 }
16 }
這就是一個後處理器!沒初始化一個Bean,都會調用第五步和第八步,所以,通過這一點,我們就可以增強自己的代碼!
在第八步裡面(postProcessAfterInitialization()),我們就可以編寫自己的增強。
但是,這裡注意一點就是:我們定義的這個後處理器,也是需要在配置文件中添加的。Spring在初始化bean過程中如果發現bean實現了BeanPostProcessor 介面,將會將其註冊為bean後處理器,它對spring容器下的所有bean起作用,任何bean在 初始化過程都會通過bean後處理器做額外增強操作。
如下是測試類的代碼:
public void demo1 {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
customerService.add;
customerService.find;
applicationContext.close;
}
但是我們不想讓所有的Bean 都被增強,這時候就可以使用動態代理來解決這個問題,可以做到只對某個方法進行增強。
代碼如下:
1 public Object postProcessAfterInitialization(final Object bean, String beanName)
2 throws BeansException {
3 System.out.println("第八步:初始化後執行...");
4 // 動態代理:
5 if(beanName.equals("customerService")){
6 Object proxy = Proxy.newProxyInstance(bean.getClass.getClassLoader, bean.getClass.getInterfaces , new InvocationHandler {
7 // 調用目標方法的時候,調用invoke方法.
8 public Object invoke(Object proxy, Method method, Object[] args)
9 throws Throwable {
10 if("add".equals(method.getName)){
11 System.out.println("許可權校驗...");
12 Object result = method.invoke(bean, args);
13 System.out.println("許可權校驗後。。。");
14 //System.out.println(System.currentTimeMillis);
15 return result;
16 }
17 return method.invoke(bean, args);
18 }
19 });
20 return proxy;
21 }
22 return bean;
23 }
這裡用到了動態代理,只對customerService的add方法進行增強!!!
這裡還要注意一點,我們這用的是JDK的動態代理,所以被代理的類必須實現某個介面才行!!!,所以,customerService是實現類介面的類!
而測試結果就很明顯了:
在調用add方法之後,會自動調用代理方法中的兩個輸出語句!
其實後面學習的動態代理用到的就是後處理Bean的知識.
※SQL Server Alwayson創建代理作業注意事項
※python中全局變數和局部變數的一個小坑
※ABP從入門到精通(3):aspnet-zero-core 使用Redis緩存
※SQL SERVER Buffer Pool擴展
※原生js之千位分隔符
TAG:達人科技 |
※Spring Bean的生命周期(詳細)
※Spring Bean的生命周期(比較詳細)
※Spring Bean的生命周期(非常詳細)
※Spring IoC之bean生命周期及相關介面使用
※郎才女貌,Frances Bean與Matthew Cook共度假期
※孕期胎教音樂之純音精選系列:Caribbean Blue-Enya
※Intel公布BeanCanyon NUC售價
※Spring中BeanFactory和ApplicationContext 的區別
※SpringBoot中如何進行Bean配置
※Supreme BOGO系列公布!Beanie帽子本周即將發售
※Jack and the Beanstalk 傑克與豆莖
※深入 SpringBoot : 怎樣排查 expectedsinglematchingbeanbutfound 2 的異常
※MO&Co. × YOHO!GIRL|Sunflower Bean帶你去草莓音樂節~
※Intel新一代NUC Bean Canyon即將發布5款新品
※Spring核心——Stereotype組件與Bean掃描
※Intel新一代NUC Bean Canyon曝光:搭載Iris核顯8代酷睿
※Intel NUC迷你電腦套機曝光,代號Bean Canyon
※Spring源碼系列:依賴注入(二)createBean
※揭露《Pirates of the Caribbean》重啟版電影沒有 Johnny Depp 真正主因
※不再續航 ? Disney 傳出將重啟《Pirates of the Caribbean》系列電影