一、前言
二、目標
三、設計
四、實現
1. 工程結構
2. 定義標記接口
3. 容器感知類
4. 包裝處理器(ApplicationContextAwareProcessor)
5. 注冊 BeanPostProcessor
6. 感知調用操作
五、測試
1. 事先準備
2. 配置文件
3. 單元測試
六、總結
七、系列推薦
同事寫的代碼,我竟絲毫看不懂!
大佬的代碼,就像“賴蛤蟆泡青蛙,長的丑玩的花”:一個類實現了多個接口、繼承的類又繼承了其他類、接口還可以和接口繼承、實現接口的抽象類再由類實現抽象類方法、類A繼承的類B實現了類A實現的接口C,等等。
看上去復雜又難懂
的代碼,卻又能一次次滿足需求的高效迭代和順利擴展,而像螺絲釘一樣搬磚的你,只是在大佬
寫的代碼里,完成某個接口下的一小塊功能,甚至寫完了也不知道怎么就被調用運行了,整個過程像看 Spring 源碼一樣神奇,跳來跳去的摸不著頭緒!
其實這主要是因為你的代碼是否運用了設計模式,當然設計模式也沒那么神奇,就像你們兩家都是120平米的房子,他家有三室兩廳一廚一衛,南北通透,全陽采光。但你家就不一樣了,你家是鍋碗瓢盆、衛浴馬桶、沙發茶幾還有那1.8的雙人床,在120平米的房子里敞開了放,沒有動靜隔離,也沒有干濕分離,純自由發揮。所以你的代碼看上去就亂的很!
?目前已實現的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 對象的定義和注冊,以及在操作 Bean 對象過程中執行的,BeanFactoryPostProcessor、BeanPostProcessor、InitializingBean、DisposableBean,以及在 XML 新增的一些配置處理,讓我們可以 Bean 對象有更強的操作性。
那么,如果我們想獲得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等這些能力做一些擴展框架的使用時該怎么操作呢。所以我們本章節希望在 Spring 框架中提供一種能感知容器操作的接口,如果誰實現了這樣的一個接口,就可以獲取接口入參中的各類能力。
?如果說我希望拿到 Spring 框架中一些提供的資源,那么首先需要考慮以一個什么方式去獲取,之后你定義出來的獲取方式,在 Spring 框架中該怎么去承接,實現了這兩項內容,就可以擴展出你需要的一些屬于 Spring 框架本身的能力了。
在關于
Bean 對象實例化階段我們操作過一些額外定義、屬性、初始化和銷毀的操作,其實我們如果像獲取 Spring 一些如
BeanFactory、ApplicationContext
時,也可以通過此類方式進行實現。那么我們需要定義一個標記性的接口,這個接口不需要有方法,它只起到標記作用就可以,而具體的功能由繼承此接口的其他功能性接口定義具體方法,最終這個接口就可以通過 instanceof
進行判斷和調用了。整體設計結構如下圖:
ApplicationContextAwareProcessor
操作,最后由 AbstractAutowireCapableBeanFactory 創建 createBean 時處理相應的調用操作。
? ? 關于 applyBeanPostProcessorsBeforeInitialization 已經在前面章節中實現過,如果忘記可以往前翻翻
? ?small-spring-step-08
└──?src
????├──?main
????│???└──?java
????│???????└──?cn.bugstack.springframework
????│???????????├──?beans
????│???????????│???├──?factory
????│???????????│???│???├──?factory
????│???????????│???│???│???├──?AutowireCapableBeanFactory.java
????│???????????│???│???│???├──?BeanDefinition.java
????│???????????│???│???│???├──?BeanFactoryPostProcessor.java
????│???????????│???│???│???├──?BeanPostProcessor.java
????│???????????│???│???│???├──?BeanReference.java
????│???????????│???│???│???├──?ConfigurableBeanFactory.java
????│???????????│???│???│???└──?SingletonBeanRegistry.java
????│???????????│???│???├──?support
????│???????????│???│???│???├──?AbstractAutowireCapableBeanFactory.java
????│???????????│???│???│???├──?AbstractBeanDefinitionReader.java
????│???????????│???│???│???├──?AbstractBeanFactory.java
????│???????????│???│???│???├──?BeanDefinitionReader.java
????│???????????│???│???│???├──?BeanDefinitionRegistry.java
????│???????????│???│???│???├──?CglibSubclassingInstantiationStrategy.java
????│???????????│???│???│???├──?DefaultListableBeanFactory.java
????│???????????│???│???│???├──?DefaultSingletonBeanRegistry.java
????│???????????│???│???│???├──?DisposableBeanAdapter.java
????│???????????│???│???│???├──?InstantiationStrategy.java
????│???????????│???│???│???└──?SimpleInstantiationStrategy.java??
????│???????????│???│???├──?support
????│???????????│???│???│???└──?XmlBeanDefinitionReader.java
????│???????????│???│???├──?Aware.java
????│???????????│???│???├──?BeanClassLoaderAware.java
????│???????????│???│???├──?BeanFactory.java
????│???????????│???│???├──?BeanFactoryAware.java
????│???????????│???│???├──?BeanNameAware.java
????│???????????│???│???├──?ConfigurableListableBeanFactory.java
????│???????????│???│???├──?DisposableBean.java
????│???????????│???│???├──?HierarchicalBeanFactory.java
????│???????????│???│???├──?InitializingBean.java
????│???????????│???│???└──?ListableBeanFactory.java
????│???????????│???├──?BeansException.java
????│???????????│???├──?PropertyValue.java
????│???????????│???└──?PropertyValues.java?
????│???????????├──?context
????│???????????│???├──?support
????│???????????│???│???├──?AbstractApplicationContext.java?
????│???????????│???│???├──?AbstractRefreshableApplicationContext.java?
????│???????????│???│???├──?AbstractXmlApplicationContext.java?
????│???????????│???│???├──?ApplicationContextAwareProcessor.java?
????│???????????│???│???└──?ClassPathXmlApplicationContext.java?
????│???????????│???├──?ApplicationContext.java?
????│???????????│???├──?ApplicationContextAware.java?
????│???????????│???└──?ConfigurableApplicationContext.java
????│???????????├──?core.io
????│???????????│???├──?ClassPathResource.java?
????│???????????│???├──?DefaultResourceLoader.java?
????│???????????│???├──?FileSystemResource.java?
????│???????????│???├──?Resource.java?
????│???????????│???├──?ResourceLoader.java?
????│???????????│???└──?UrlResource.java
????│???????????└──?utils
????│???????????????└──?ClassUtils.java
????└──?test
????????└──?java
????????????└──?cn.bugstack.springframework.test
????????????????├──?bean
????????????????│???├──?UserDao.java
????????????????│???└──?UserService.java
????????????????└──?ApiTest.java
?工程源碼:公眾號「bugstack蟲洞?!?#xff0c;回復:Spring 專欄,獲取完整源碼
Spring 感知接口的設計和實現類關系,如圖 9-2
addBeanPostProcessor
,再由 ?createBean ?統一調用 applyBeanPostProcessorsBeforeInitialization 時進行操作。cn.bugstack.springframework.beans.factory.Aware
/**
?*?Marker?superinterface?indicating?that?a?bean?is?eligible?to?be
?*?notified?by?the?Spring?container?of?a?particular?framework?object
?*?through?a?callback-style?method.??Actual?method?signature?is
?*?determined?by?individual?subinterfaces,?but?should?typically
?*?consist?of?just?one?void-returning?method?that?accepts?a?single
?*?argument.
?*
?*?標記類接口,實現該接口可以被Spring容器感知
?*
?*/
public?interface?Aware?{
}
?cn.bugstack.springframework.beans.factory.BeanFactoryAware
public?interface?BeanFactoryAware?extends?Aware?{
???void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException;
}
?cn.bugstack.springframework.beans.factory.BeanClassLoaderAware
public?interface?BeanClassLoaderAware?extends?Aware{
????void?setBeanClassLoader(ClassLoader?classLoader);
}
?cn.bugstack.springframework.beans.factory.BeanNameAware
public?interface?BeanNameAware?extends?Aware?{
????void?setBeanName(String?name);
}
?cn.bugstack.springframework.context.ApplicationContextAware
public?interface?ApplicationContextAware?extends?Aware?{
????void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException;
}
?cn.bugstack.springframework.context.support.ApplicationContextAwareProcessor
public?class?ApplicationContextAwareProcessor?implements?BeanPostProcessor?{
????private?final?ApplicationContext?applicationContext;
????public?ApplicationContextAwareProcessor(ApplicationContext?applicationContext)?{
????????this.applicationContext?=?applicationContext;
????}
????@Override
????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????if?(bean?instanceof?ApplicationContextAware){
????????????((ApplicationContextAware)?bean).setApplicationContext(applicationContext);
????????}
????????return?bean;
????}
????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????return?bean;
????}
}
?cn.bugstack.springframework.context.support.AbstractApplicationContext
public?abstract?class?AbstractApplicationContext?extends?DefaultResourceLoader?implements?ConfigurableApplicationContext?{
????@Override
????public?void?refresh()?throws?BeansException?{
????????//?1.?創建?BeanFactory,并加載?BeanDefinition
????????refreshBeanFactory();
????????//?2.?獲取?BeanFactory
????????ConfigurableListableBeanFactory?beanFactory?=?getBeanFactory();
????????//?3.?添加?ApplicationContextAwareProcessor,讓繼承自?ApplicationContextAware?的?Bean?對象都能感知所屬的?ApplicationContext
????????beanFactory.addBeanPostProcessor(new?ApplicationContextAwareProcessor(this));
????????//?4.?在?Bean?實例化之前,執行?BeanFactoryPostProcessor?(Invoke?factory?processors?registered?as?beans?in?the?context.)
????????invokeBeanFactoryPostProcessors(beanFactory);
????????//?5.?BeanPostProcessor?需要提前于其他?Bean?對象實例化之前執行注冊操作
????????registerBeanPostProcessors(beanFactory);
????????//?6.?提前實例化單例Bean對象
????????beanFactory.preInstantiateSingletons();
????}
????
??//?...???
}????
?cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
public?abstract?class?AbstractAutowireCapableBeanFactory?extends?AbstractBeanFactory?implements?AutowireCapableBeanFactory?{
????private?InstantiationStrategy?instantiationStrategy?=?new?CglibSubclassingInstantiationStrategy();
????@Override
????protected?Object?createBean(String?beanName,?BeanDefinition?beanDefinition,?Object[]?args)?throws?BeansException?{
????????Object?bean?=?null;
????????try?{
????????????bean?=?createBeanInstance(beanDefinition,?beanName,?args);
????????????//?給?Bean?填充屬性
????????????applyPropertyValues(beanName,?bean,?beanDefinition);
????????????//?執行?Bean?的初始化方法和?BeanPostProcessor?的前置和后置處理方法
????????????bean?=?initializeBean(beanName,?bean,?beanDefinition);
????????}?catch?(Exception?e)?{
????????????throw?new?BeansException("Instantiation?of?bean?failed",?e);
????????}
????????//?注冊實現了?DisposableBean?接口的?Bean?對象
????????registerDisposableBeanIfNecessary(beanName,?bean,?beanDefinition);
????????addSingleton(beanName,?bean);
????????return?bean;
????}
????private?Object?initializeBean(String?beanName,?Object?bean,?BeanDefinition?beanDefinition)?{
????????//?invokeAwareMethods
????????if?(bean?instanceof?Aware)?{
????????????if?(bean?instanceof?BeanFactoryAware)?{
????????????????((BeanFactoryAware)?bean).setBeanFactory(this);
????????????}
????????????if?(bean?instanceof?BeanClassLoaderAware){
????????????????((BeanClassLoaderAware)?bean).setBeanClassLoader(getBeanClassLoader());
????????????}
????????????if?(bean?instanceof?BeanNameAware)?{
????????????????((BeanNameAware)?bean).setBeanName(beanName);
????????????}
????????}
????????//?1.?執行?BeanPostProcessor?Before?處理
????????Object?wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(bean,?beanName);
????????//?執行?Bean?對象的初始化方法
????????try?{
????????????invokeInitMethods(beanName,?wrappedBean,?beanDefinition);
????????}?catch?(Exception?e)?{
????????????throw?new?BeansException("Invocation?of?init?method?of?bean["?+?beanName?+?"]?failed",?e);
????????}
????????//?2.?執行?BeanPostProcessor?After?處理
????????wrappedBean?=?applyBeanPostProcessorsAfterInitialization(bean,?beanName);
????????return?wrappedBean;
????}
????@Override
????public?Object?applyBeanPostProcessorsBeforeInitialization(Object?existingBean,?String?beanName)?throws?BeansException?{
????????Object?result?=?existingBean;
????????for?(BeanPostProcessor?processor?:?getBeanPostProcessors())?{
????????????Object?current?=?processor.postProcessBeforeInitialization(result,?beanName);
????????????if?(null?==?current)?return?result;
????????????result?=?current;
????????}
????????return?result;
????}
????@Override
????public?Object?applyBeanPostProcessorsAfterInitialization(Object?existingBean,?String?beanName)?throws?BeansException?{
????????Object?result?=?existingBean;
????????for?(BeanPostProcessor?processor?:?getBeanPostProcessors())?{
????????????Object?current?=?processor.postProcessAfterInitialization(result,?beanName);
????????????if?(null?==?current)?return?result;
????????????result?=?current;
????????}
????????return?result;
????}
}
?bean instanceof Aware
,調用了三個接口方法,
? ? BeanFactoryAware.setBeanFactory(this)
、
? ? BeanClassLoaderAware.setBeanClassLoader(getBeanClassLoader())
、
? ? BeanNameAware.setBeanName(beanName)
,這樣就能通知到已經實現了此接口的類。ApplicationContextAwareProcessor
,此時在這個方法中也會被調用到具體的類實現,得到一個 ApplicationContex 屬性。cn.bugstack.springframework.test.bean.UserDao
public?class?UserDao?{
????private?static?Map<String,?String>?hashMap?=?new?HashMap<>();
????public?void?initDataMethod(){
????????System.out.println("執行:init-method");
????????hashMap.put("10001",?"小傅哥");
????????hashMap.put("10002",?"八杯水");
????????hashMap.put("10003",?"阿毛");
????}
????public?void?destroyDataMethod(){
????????System.out.println("執行:destroy-method");
????????hashMap.clear();
????}
????public?String?queryUserName(String?uId)?{
????????return?hashMap.get(uId);
????}
}
?cn.bugstack.springframework.test.bean.UserService
public?class?UserService?implements?BeanNameAware,?BeanClassLoaderAware,?ApplicationContextAware,?BeanFactoryAware?{
????private?ApplicationContext?applicationContext;
????private?BeanFactory?beanFactory;
????private?String?uId;
????private?String?company;
????private?String?location;
????private?UserDao?userDao;
????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????this.beanFactory?=?beanFactory;
????}
????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????this.applicationContext?=?applicationContext;
????}
????@Override
????public?void?setBeanName(String?name)?{
????????System.out.println("Bean Name is:"?+?name);
????}
????@Override
????public?void?setBeanClassLoader(ClassLoader?classLoader)?{
????????System.out.println("ClassLoader:"?+?classLoader);
????}
????//?...get/set
}
?基礎配置,無BeanFactoryPostProcessor、BeanPostProcessor,實現類
<?xml?version="1.0"?encoding="UTF-8"?>
<beans>
????<bean?id="userDao"?class="cn.bugstack.springframework.test.bean.UserDao"?init-method="initDataMethod"?destroy-method="destroyDataMethod"/>
????<bean?id="userService"?class="cn.bugstack.springframework.test.bean.UserService">
????????<property?name="uId"?value="10001"/>
????????<property?name="company"?value="騰訊"/>
????????<property?name="location"?value="深圳"/>
????????<property?name="userDao"?ref="userDao"/>
????</bean>
</beans>
?@Test
public?void?test_xml()?{
????//?1.初始化?BeanFactory
????ClassPathXmlApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext("classpath:spring.xml");
????applicationContext.registerShutdownHook();??????
????//?2.?獲取Bean對象調用方法
????UserService?userService?=?applicationContext.getBean("userService",?UserService.class);
????String?result?=?userService.queryUserInfo();
????System.out.println("測試結果:"?+?result);
????System.out.println("ApplicationContextAware:"+userService.getApplicationContext());
????System.out.println("BeanFactoryAware:"+userService.getBeanFactory());
}
?測試結果
執行:init-method
ClassLoader:sun.misc.Launcher$AppClassLoader@14dad5dc
Bean Name is:userService
測試結果:小傅哥,騰訊,深圳
ApplicationContextAware:cn.bugstack.springframework.context.support.ClassPathXmlApplicationContext@5ba23b66
BeanFactoryAware:cn.bugstack.springframework.beans.factory.support.DefaultListableBeanFactory@2ff4f00f
執行:destroy-method
Process?finished?with?exit?code?0
?目前關于 Spring 框架的實現中,某些功能點已經越來趨向于完整,尤其是 Bean 對象的生命周期,已經有了很多的體現。整體總結如下圖:
本章節關于 Aware 的感知接口的四個繼承接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 的實現,又擴展了 Spring 的功能。如果你有做過關于 Spring 中間件的開發那么一定會大量用到這些類,現在你不只是用過,而且還知道他們都是什么時候觸達的,在以后想排查類的實例化順序也可以有一個清晰的思路了。
每一章節內容的實現都是在以設計模式為核心的結構上填充各項模塊的功能,單純的操作編寫代碼并不會有太多收獲,一定是要理解為什么這么設計,這么設計的好處是什么,怎么就那么多接口和抽象類的應用,這些才是 Spring 框架學習的核心所在。
|