日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
虎行有雨,定義標(biāo)記類型Aware接口,實(shí)現(xiàn)感知容器對(duì)象

 [[407936]]

本文轉(zhuǎn)載自微信公眾號(hào)「bugstack蟲洞?!?,作者小傅哥 。轉(zhuǎn)載本文請(qǐng)聯(lián)系bugstack蟲洞棧公眾號(hào)。

目前創(chuàng)新互聯(lián)已為成百上千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、婺源網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

目錄

  • 一、前言
  • 二、目標(biāo)
  • 三、設(shè)計(jì)
  • 四、實(shí)現(xiàn)
    • 1. 工程結(jié)構(gòu)
    • 2. 定義標(biāo)記接口
    • 3. 容器感知類
    • 4. 包裝處理器(ApplicationContextAwareProcessor)
    • 5. 注冊(cè) BeanPostProcessor
    • 6. 感知調(diào)用操作
  • 五、測(cè)試
    • 1. 事先準(zhǔn)備
    • 2. 配置文件
    • 3. 單元測(cè)試
  • 六、總結(jié)

一、前言

同事寫的代碼,我竟絲毫看不懂!

大佬的代碼,就像“賴蛤蟆泡青蛙,張的丑玩的花”:一個(gè)類實(shí)現(xiàn)了多個(gè)接口、繼承的類又繼承了其他類、接口還可以和接口繼承、實(shí)現(xiàn)接口的抽象類再由類實(shí)現(xiàn)抽象類方法、類A繼承的類B實(shí)現(xiàn)了類A實(shí)現(xiàn)的接口C,等等。

看上去復(fù)雜又難懂的代碼,卻又能一次次滿足需求的高效迭代和順利擴(kuò)展,而像螺絲釘一樣搬磚的你,只是在大佬寫的代碼里,完成某個(gè)接口下的一小塊功能,甚至寫完了也不知道怎么就被調(diào)用運(yùn)行了,整個(gè)過程像看 Spring 源碼一樣神奇,跳來跳去的摸不著頭緒!

其實(shí)這主要是因?yàn)槟愕拇a是否運(yùn)用了設(shè)計(jì)模式,當(dāng)然設(shè)計(jì)模式也沒那么神奇,就像你們兩家都是120平米的房子,他家有三室兩廳一廚一衛(wèi),南北通透,全陽(yáng)采光。但你家就不一樣了,你家是鍋碗瓢盆、衛(wèi)浴馬桶、沙發(fā)茶幾還有那1.8的雙人床,在120平米的房子里敞開了放,沒有動(dòng)靜隔離,也沒有干濕分離,純自由發(fā)揮。所以你的代碼看上去就亂的很!

二、目標(biāo)

目前已實(shí)現(xiàn)的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 對(duì)象的定義和注冊(cè),以及在操作 Bean 對(duì)象過程中執(zhí)行的,BeanFactoryPostProcessor、BeanPostProcessor、InitializingBean、DisposableBean,以及在 XML 新增的一些配置處理,讓我們可以 Bean 對(duì)象有更強(qiáng)的操作性。

那么,如果我們想獲得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等這些能力做一些擴(kuò)展框架的使用時(shí)該怎么操作呢。所以我們本章節(jié)希望在 Spring 框架中提供一種能感知容器操作的接口,如果誰(shuí)實(shí)現(xiàn)了這樣的一個(gè)接口,就可以獲取接口入?yún)⒅械母黝惸芰Α?/p>

三、設(shè)計(jì)

如果說我希望拿到 Spring 框架中一些提供的資源,那么首先需要考慮以一個(gè)什么方式去獲取,之后你定義出來的獲取方式,在 Spring 框架中該怎么去承接,實(shí)現(xiàn)了這兩項(xiàng)內(nèi)容,就可以擴(kuò)展出你需要的一些屬于 Spring 框架本身的能力了。

在關(guān)于 Bean 對(duì)象實(shí)例化階段我們操作過一些額外定義、屬性、初始化和銷毀的操作,其實(shí)我們?nèi)绻瘾@取 Spring 一些如 BeanFactory、ApplicationContext 時(shí),也可以通過此類方式進(jìn)行實(shí)現(xiàn)。那么我們需要定義一個(gè)標(biāo)記性的接口,這個(gè)接口不需要有方法,它只起到標(biāo)記作用就可以,而具體的功能由繼承此接口的其他功能性接口定義具體方法,最終這個(gè)接口就可以通過 instanceof 進(jìn)行判斷和調(diào)用了。整體設(shè)計(jì)結(jié)構(gòu)如下圖:

  • 定義接口 Aware,在 Spring 框架中它是一種感知標(biāo)記性接口,具體的子類定義和實(shí)現(xiàn)能感知容器中的相關(guān)對(duì)象。也就是通過這個(gè)橋梁,向具體的實(shí)現(xiàn)類中提供容器服務(wù)
  • 繼承 Aware 的接口包括:BeanFactoryAware、BeanClassLoaderAware、BeanNameAware和ApplicationContextAware,當(dāng)然在 Spring 源碼中還有一些其他關(guān)于注解的,不過目前我們還是用不到。
  • 在具體的接口實(shí)現(xiàn)過程中你可以看到,一部分(BeanFactoryAware、BeanClassLoaderAware、BeanNameAware)在 factory 的 support 文件夾下,另外 ApplicationContextAware 是在 context 的 support 中,這是因?yàn)椴煌膬?nèi)容獲取需要在不同的包下提供。所以,在 AbstractApplicationContext 的具體實(shí)現(xiàn)中會(huì)用到向 beanFactory 添加 BeanPostProcessor 內(nèi)容的 ApplicationContextAwareProcessor 操作,最后由 AbstractAutowireCapableBeanFactory 創(chuàng)建 createBean 時(shí)處理相應(yīng)的調(diào)用操作。關(guān)于 applyBeanPostProcessorsBeforeInitialization 已經(jīng)在前面章節(jié)中實(shí)現(xiàn)過,如果忘記可以往前翻翻

四、實(shí)現(xiàn)

1. 工程結(jié)構(gòu)

 
 
 
 
  1. small-spring-step-08 
  2. └── src 
  3.     ├── main 
  4.     │   └── java 
  5.     │       └── cn.bugstack.springframework 
  6.     │           ├── beans 
  7.     │           │   ├── factory 
  8.     │           │   │   ├── factory 
  9.     │           │   │   │   ├── AutowireCapableBeanFactory.java 
  10.     │           │   │   │   ├── BeanDefinition.java 
  11.     │           │   │   │   ├── BeanFactoryPostProcessor.java 
  12.     │           │   │   │   ├── BeanPostProcessor.java 
  13.     │           │   │   │   ├── BeanReference.java 
  14.     │           │   │   │   ├── ConfigurableBeanFactory.java 
  15.     │           │   │   │   └── SingletonBeanRegistry.java 
  16.     │           │   │   ├── support 
  17.     │           │   │   │   ├── AbstractAutowireCapableBeanFactory.java 
  18.     │           │   │   │   ├── AbstractBeanDefinitionReader.java 
  19.     │           │   │   │   ├── AbstractBeanFactory.java 
  20.     │           │   │   │   ├── BeanDefinitionReader.java 
  21.     │           │   │   │   ├── BeanDefinitionRegistry.java 
  22.     │           │   │   │   ├── CglibSubclassingInstantiationStrategy.java 
  23.     │           │   │   │   ├── DefaultListableBeanFactory.java 
  24.     │           │   │   │   ├── DefaultSingletonBeanRegistry.java 
  25.     │           │   │   │   ├── DisposableBeanAdapter.java 
  26.     │           │   │   │   ├── InstantiationStrategy.java 
  27.     │           │   │   │   └── SimpleInstantiationStrategy.java   
  28.     │           │   │   ├── support 
  29.     │           │   │   │   └── XmlBeanDefinitionReader.java 
  30.     │           │   │   ├── Aware.java 
  31.     │           │   │   ├── BeanClassLoaderAware.java 
  32.     │           │   │   ├── BeanFactory.java 
  33.     │           │   │   ├── BeanFactoryAware.java 
  34.     │           │   │   ├── BeanNameAware.java 
  35.     │           │   │   ├── ConfigurableListableBeanFactory.java 
  36.     │           │   │   ├── DisposableBean.java 
  37.     │           │   │   ├── HierarchicalBeanFactory.java 
  38.     │           │   │   ├── InitializingBean.java 
  39.     │           │   │   └── ListableBeanFactory.java 
  40.     │           │   ├── BeansException.java 
  41.     │           │   ├── PropertyValue.java 
  42.     │           │   └── PropertyValues.java  
  43.     │           ├── context 
  44.     │           │   ├── support 
  45.     │           │   │   ├── AbstractApplicationContext.java  
  46.     │           │   │   ├── AbstractRefreshableApplicationContext.java  
  47.     │           │   │   ├── AbstractXmlApplicationContext.java  
  48.     │           │   │   ├── ApplicationContextAwareProcessor.java  
  49.     │           │   │   └── ClassPathXmlApplicationContext.java  
  50.     │           │   ├── ApplicationContext.java  
  51.     │           │   ├── ApplicationContextAware.java  
  52.     │           │   └── ConfigurableApplicationContext.java 
  53.     │           ├── core.io 
  54.     │           │   ├── ClassPathResource.java  
  55.     │           │   ├── DefaultResourceLoader.java  
  56.     │           │   ├── FileSystemResource.java  
  57.     │           │   ├── Resource.java  
  58.     │           │   ├── ResourceLoader.java  
  59.     │           │   └── UrlResource.java 
  60.     │           └── utils 
  61.     │               └── ClassUtils.java 
  62.     └── test 
  63.         └── java 
  64.             └── cn.bugstack.springframework.test 
  65.                 ├── bean 
  66.                 │   ├── UserDao.java 
  67.                 │   └── UserService.java 
  68.                 └── ApiTest.java 

Spring 感知接口的設(shè)計(jì)和實(shí)現(xiàn)類關(guān)系,如圖 9-2

圖 9-2

  • 以上整個(gè)類關(guān)系就是關(guān)于 Aware 感知的定義和對(duì)容器感知的實(shí)現(xiàn)。
  • Aware 有四個(gè)繼承的接口,其他這些接口的繼承都是為了繼承一個(gè)標(biāo)記,有了標(biāo)記的存在更方便類的操作和具體判斷實(shí)現(xiàn)。
  • 另外由于 ApplicationContext 并不是在 AbstractAutowireCapableBeanFactory 中 createBean 方法下的內(nèi)容,所以需要像容器中注冊(cè) addBeanPostProcessor ,再由 createBean 統(tǒng)一調(diào)用 applyBeanPostProcessorsBeforeInitialization 時(shí)進(jìn)行操作。

2. 定義標(biāo)記接口

 
 
 
 
  1. /** 
  2.  * Marker superinterface indicating that a bean is eligible to be 
  3.  * notified by the Spring container of a particular framework object 
  4.  * through a callback-style method.  Actual method signature is 
  5.  * determined by individual subinterfaces, but should typically 
  6.  * consist of just one void-returning method that accepts a single 
  7.  * argument. 
  8.  * 
  9.  * 標(biāo)記類接口,實(shí)現(xiàn)該接口可以被Spring容器感知 
  10.  * 
  11.  */ 
  12. public interface Aware { 

在 Spring 中有特別多類似這樣的標(biāo)記接口的設(shè)計(jì)方式,它們的存在就像是一種標(biāo)簽一樣,可以方便統(tǒng)一摘取出屬于此類接口的實(shí)現(xiàn)類,通常會(huì)有 instanceof 一起判斷使用。

3. 容器感知類

3.1 BeanFactoryAware

 
 
 
 
  1. public interface BeanFactoryAware extends Aware { 
  2.  
  3.    void setBeanFactory(BeanFactory beanFactory) throws BeansException; 
  4.  
  • Interface to be implemented by beans that wish to be aware of their owning {@link BeanFactory}.
  • 實(shí)現(xiàn)此接口,既能感知到所屬的 BeanFactory

3.2 BeanClassLoaderAware

cn.bugstack.springframework.beans.factory.BeanClassLoaderAware

 
 
 
 
  1. public interface BeanClassLoaderAware extends Aware{ 
  2.  
  3.     void setBeanClassLoader(ClassLoader classLoader); 
  4.  
  • Callback that allows a bean to be aware of the bean{@link ClassLoader class loader}; that is, the class loader used by the present bean factory to load bean classes.
  • 實(shí)現(xiàn)此接口,既能感知到所屬的 ClassLoader

3.3 BeanNameAware

cn.bugstack.springframework.beans.factory.BeanNameAware

 
 
 
 
  1. public interface BeanClassLoaderAware extends Aware{ 
  2.  
  3.     void setBeanClassLoader(ClassLoader classLoader); 
  4.  
  • Interface to be implemented by beans that want to be aware of their bean name in a bean factory.
  • 實(shí)現(xiàn)此接口,既能感知到所屬的 BeanName

3.4 ApplicationContextAware

cn.bugstack.springframework.context.ApplicationContextAware

 
 
 
 
  1. public interface ApplicationContextAware extends Aware { 
  2.  
  3.     void setApplicationContext(ApplicationContext applicationContext) throws BeansException; 
  4.  
  • Interface to be implemented by any object that wishes to be notifiedof the {@link ApplicationContext} that it runs in.
  • 實(shí)現(xiàn)此接口,既能感知到所屬的 ApplicationContext

4. 包裝處理器(ApplicationContextAwareProcessor)

cn.bugstack.springframework.context.support.ApplicationContextAwareProcessor

 
 
 
 
  1. public class ApplicationContextAwareProcessor implements BeanPostProcessor { 
  2.  
  3.     private final ApplicationContext applicationContext; 
  4.  
  5.     public ApplicationContextAwareProcessor(ApplicationContext applicationContext) { 
  6.         this.applicationContext = applicationContext; 
  7.     } 
  8.  
  9.     @Override 
  10.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
  11.         if (bean instanceof ApplicationContextAware){ 
  12.             ((ApplicationContextAware) bean).setApplicationContext(applicationContext); 
  13.         } 
  14.         return bean; 
  15.     } 
  16.  
  17.     @Override 
  18.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
  19.         return bean; 
  20.     } 
  21.  

由于 ApplicationContext 的獲取并不能直接在創(chuàng)建 Bean 時(shí)候就可以拿到,所以需要在 refresh 操作時(shí),把 ApplicationContext 寫入到一個(gè)包裝的 BeanPostProcessor 中去,再由 AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization 方法調(diào)用。

5. 注冊(cè) BeanPostProcessor

cn.bugstack.springframework.context.support.AbstractApplicationContext

 
 
 
 
  1. public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { 
  2.  
  3.     @Override 
  4.     public void refresh() throws BeansException { 
  5.         // 1. 創(chuàng)建 BeanFactory,并加載 BeanDefinition 
  6.         refreshBeanFactory(); 
  7.  
  8.         // 2. 獲取 BeanFactory 
  9.         ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 
  10.  
  11.         // 3. 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對(duì)象都能感知所屬的 ApplicationContext 
  12.         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 
  13.  
  14.         // 4. 在 Bean 實(shí)例化之前,執(zhí)行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) 
  15.         invokeBeanFactoryPostProcessors(beanFactory); 
  16.  
  17.         // 5. BeanPostProcessor 需要提前于其他 Bean 對(duì)象實(shí)例化之前執(zhí)行注冊(cè)操作 
  18.         registerBeanPostProcessors(beanFactory); 
  19.  
  20.         // 6. 提前實(shí)例化單例Bean對(duì)象 
  21.         beanFactory.preInstantiateSingletons(); 
  22.     } 
  23.      
  24.   // ...    
  25. }     
  • refresh() 方法就是整個(gè) Spring 容器的操作過程,與上一章節(jié)對(duì)比,本次新增加了關(guān)于 addBeanPostProcessor 的操作。
  • 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對(duì)象都能感知所屬的 ApplicationContext。

6. 感知調(diào)用操作

cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

 
 
 
 
  1. public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { 
  2.  
  3.     private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); 
  4.  
  5.     @Override 
  6.     protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { 
  7.         Object bean = null; 
  8.         try { 
  9.             bean = createBeanInstance(beanDefinition, beanName, args); 
  10.             // 給 Bean 填充屬性 
  11.             applyPropertyValues(beanName, bean, beanDefinition); 
  12.             // 執(zhí)行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置處理方法 
  13.             bean = initializeBean(beanName, bean, beanDefinition); 
  14.         } catch (Exception e) { 
  15.             throw new BeansException("Instantiation of bean failed", e); 
  16.         } 
  17.  
  18.         // 注冊(cè)實(shí)現(xiàn)了 DisposableBean 接口的 Bean 對(duì)象 
  19.         registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); 
  20.  
  21.         addSingleton(beanName, bean); 
  22.         return bean; 
  23.     } 
  24.  
  25.     private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { 
  26.  
  27.         // invokeAwareMethods 
  28.         if (bean instanceof Aware) { 
  29.             if (bean instanceof BeanFactoryAware) { 
  30.                 ((BeanFactoryAware) bean).setBeanFactory(this); 
  31.             } 
  32.             if (bean instanceof BeanClassLoaderAware){ 
  33.                 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); 
  34.             } 
  35.             if (bean instanceof BeanNameAware) { 
  36.                 ((BeanNameAware) bean).setBeanName(beanName); 
  37.             } 
  38.         } 
  39.  
  40.         // 1. 執(zhí)行 BeanPostProcessor Before 處理 
  41.         Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); 
  42.  
  43.         // 執(zhí)行 Bean 對(duì)象的初始化方法 
  44.         try { 
  45.             invokeInitMethods(beanName, wrappedBean, beanDefinition); 
  46.         } catch (Exception e) { 
  47.             throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); 
  48.         } 
  49.  
  50.         // 2. 執(zhí)行 BeanPostProcessor After 處理 
  51.         wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 
  52.         return wrappedBean; 
  53.     } 
  54.  
  55.  
  56.  
  57.     @Override 
  58.     public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { 
  59.         Object result = existingBean; 
  60.         for (BeanPostProcessor processor : getBeanPostProcessors()) { 
  61.             Object current = processor.postProcessBeforeInitialization(result, beanName); 
  62.             if (null == current) return result; 
  63.             result = current; 
  64.         } 
  65.         return result; 
  66.     } 
  67.  
  68.     @Override 
  69.     public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { 
  70.         Object result = existingBean; 
  71.         for (BeanPostProcessor processor : getBeanPostProcessors()) { 
  72.             Object current = processor.postProcessAfterInitialization(result, beanName); 
  73.             if (null == current) return result; 
  74.             result = current; 
  75.         } 
  76.         return result; 
  77.     } 
  78.  
  • 這里我們?nèi)サ袅艘恍╊惖膬?nèi)容,只保留關(guān)于本次 Aware 感知接口的操作。
  • 首先在 initializeBean 中,通過判斷 bean instanceof Aware,調(diào)用了三個(gè)接口方法,BeanFactoryAware.setBeanFactory(this)、BeanClassLoaderAware.setBeanClassLoader(getBeanClassLoader())、BeanNameAware.setBeanName(beanName),這樣就能通知到已經(jīng)實(shí)現(xiàn)了此接口的類。
  • 另外我們還向 BeanPostProcessor 中添加了 ApplicationContextAwareProcessor,此時(shí)在這個(gè)方法中也會(huì)被調(diào)用到具體的類實(shí)現(xiàn),得到一個(gè) ApplicationContex 屬性。

五、測(cè)試

1. 事先準(zhǔn)備

cn.bugstack.springframework.test.bean.UserDao

 
 
 
 
  1. public class UserDao { 
  2.  
  3.     private static Map hashMap = new HashMap<>(); 
  4.  
  5.     public void initDataMethod(){ 
  6.         System.out.println("執(zhí)行:init-method"); 
  7.         hashMap.put("10001", "小傅哥"); 
  8.         hashMap.put("10002", "八杯水"); 
  9.         hashMap.put("10003", "阿毛"); 
  10.     } 
  11.  
  12.     public void destroyDataMethod(){ 
  13.         System.out.println("執(zhí)行:destroy-method"); 
  14.         hashMap.clear(); 
  15.     } 
  16.  
  17.     public String queryUserName(String uId) { 
  18.         return hashMap.get(uId); 
  19.     } 
  20.  

cn.bugstack.springframework.test.bean.UserService

 
 
 
 
  1. public class UserService implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware { 
  2.  
  3.     private ApplicationContext applicationContext; 
  4.     private BeanFactory beanFactory; 
  5.  
  6.     private String uId; 
  7.     private String company; 
  8.     private String location; 
  9.     private UserDao userDao; 
  10.  
  11.     @Override 
  12.     public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
  13.         this.beanFactory = beanFactory; 
  14.     } 
  15.  
  16.     @Override 
  17.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
  18.         this.applicationContext = applicationContext; 
  19.     } 
  20.  
  21.     @Override 
  22.     public void setBeanName(String name) { 
  23.         System.out.println("Bean Name is:" + name); 
  24.     } 
  25.  
  26.     @Override 
  27.     public void setBeanClassLoader(ClassLoader classLoader) { 
  28.         System.out.println("ClassLoader:" + classLoader); 
  29.     } 
  30.  
  31.     // ...get/set 

UserDao 本次并沒有什么改變,還是提供了關(guān)于初始化的方法,并在 Spring.xml 中提供 init-method、destroy-method 配置信息。

UserService 新增加,BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware,四個(gè)感知的實(shí)現(xiàn)類,并在類中實(shí)現(xiàn)相應(yīng)的接口方法。

2. 配置文件

基礎(chǔ)配置,無BeanFactoryPostProcessor、BeanPostProcessor,實(shí)現(xiàn)類

 
 
 
 
  1.  
  2.  
  3.  
  4.      
  5.  
  6.      
  7.          
  8.          
  9.          
  10.          
  11.      
  12.  
  13.  

 本章節(jié)中并沒有額外新增加配置信息,與上一章節(jié)內(nèi)容相同。

3. 單元測(cè)試

 
 
 
 
  1. @Test 
  2. public void test_xml() { 
  3.     // 1.初始化 BeanFactory 
  4.     ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml"); 
  5.     applicationContext.registerShutdownHook();       
  6.  
  7.     // 2. 獲取Bean對(duì)象調(diào)用方法 
  8.     UserService userService = applicationContext.getBean("userService", UserService.class); 
  9.     String result = userService.queryUserInfo(); 
  10.     System.out.println("測(cè)試結(jié)果:" + result); 
  11.     System.out.println("ApplicationContextAware:"+userService.getApplicationContext()); 
  12.     System.out.println("BeanFactoryAware:"+userService.getBeanFactory()); 
  • 測(cè)試方法中主要是添加了一寫關(guān)于新增 Aware 實(shí)現(xiàn)的調(diào)用,其他不需要調(diào)用的也打印了相應(yīng)的日志信息,可以在測(cè)試結(jié)果中看到。

測(cè)試結(jié)果

 
 
 
 
  1. 執(zhí)行:init-method 
  2. ClassLoader:sun.misc.Launcher$AppClassLoader@14dad5dc 
  3. Bean Name is:userService 
  4. 測(cè)試結(jié)果:小傅哥,騰訊,深圳 
  5. ApplicationContextAware:cn.bugstack.springframework.context.support.ClassPathXmlApplicationContext@5ba23b66 
  6. BeanFactoryAware:cn.bugstack.springframework.beans.factory.support.DefaultListableBeanFactory@2ff4f00f 
  7. 執(zhí)行:destroy-method 
  8.  
  9.  
  10.  
  11. Process finished with exit code 0 

從測(cè)試結(jié)果可以看到,本章節(jié)新增加的感知接口對(duì)應(yīng)的具體實(shí)現(xiàn)(BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware),已經(jīng)可以如期輸出結(jié)果了。

六、總結(jié)

目前關(guān)于 Spring 框架的實(shí)現(xiàn)中,某些功能點(diǎn)已經(jīng)越來趨向于完整,尤其是 Bean 對(duì)象的生命周期,已經(jīng)有了很多的體現(xiàn)。整體總結(jié)如下圖:

本章節(jié)關(guān)于 Aware 的感知接口的四個(gè)繼承接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 的實(shí)現(xiàn),又?jǐn)U展了 Spring 的功能。如果你有做過關(guān)于 Spring 中間件的開發(fā)那么一定會(huì)大量用到這些類,現(xiàn)在你不只是用過,而且還知道他們都是什么時(shí)候觸達(dá)的,在以后想排查類的實(shí)例化順序也可以有一個(gè)清晰的思路了。

每一章節(jié)內(nèi)容的實(shí)現(xiàn)都是在以設(shè)計(jì)模式為核心的結(jié)構(gòu)上填充各項(xiàng)模塊的功能,單純的操作編寫代碼并不會(huì)有太多收獲,一定是要理解為什么這么設(shè)計(jì),這么設(shè)計(jì)的好處是什么,怎么就那么多接口和抽象類的應(yīng)用,這些才是 Spring 框架學(xué)習(xí)的核心所在。


當(dāng)前標(biāo)題:虎行有雨,定義標(biāo)記類型Aware接口,實(shí)現(xiàn)感知容器對(duì)象
當(dāng)前地址:http://www.5511xx.com/article/djjdhoo.html