日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手写简版spring --8--Aware感知容器对象Aware感知容器对象

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手写简版spring --8--Aware感知容器对象Aware感知容器对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、目標

目前已實現的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 對象的定義和注冊,以及在操作 Bean 對象過程中執行的,BeanFactoryPostProcessor、BeanPostProcessor、InitializingBean、DisposableBean,以及在 XML 新增的一些配置處理,讓我們可以 Bean 對象有更強的操作性。那么,如果我們想獲得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等這些能力做一些擴展框架的使用時該怎么操作呢。所以我們本章節希望在 Spring 框架中提供一種能感知容器操作的接口,如果誰實現了這樣的一個接口,就可以獲取接口入參中的各類能力。

二、設計

如果說我希望拿到 Spring 框架中一些提供的資源,那么首先需要考慮以一個什么方式去獲取,之后你定義出來的獲取方式,在 Spring 框架中該怎么去承接,實現了這兩項內容,就可以擴展出你需要的一些屬于 Spring 框架本身的能力了。在關于 Bean 對象實例化階段我們操作過一些額外定義、屬性、初始化和銷毀的操作,其實我們如果像獲取 Spring 一些如 BeanFactory、ApplicationContext 時,也可以通過此類方式進行實現。那么我們需要定義一個標記性的接口,這個接口不需要有方法,它只起到標記作用就可以,而具體的功能由繼承此接口的其他功能性接口定義具體方法,最終這個接口就可以通過 instanceof 進行判斷和調用了。整體設計結構如下圖:

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

  • 工程結構
  • small-spring-step-08 └── src├── main│ └── java│ └── cn.bugstack.springframework│ ├── beans│ │ ├── factory│ │ │ ├── config│ │ │ │ ├── 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
  • 類依賴關系
  • 以上整個類關系就是關于 Aware 感知的定義和對容器感知的實現。
  • Aware 有四個繼承的接口,其他這些接口的繼承都是為了繼承一個標記,有了標記的存在更方便類的操作和具體判斷實現。
  • 另外由于 ApplicationContext 并不是在 AbstractAutowireCapableBeanFactory 中 createBean 方法下的內容,所以需要像容器中注冊 addBeanPostProcessor ,再由 createBean 統一調用 applyBeanPostProcessorsBeforeInitialization 時進行操作。
  • 定義標記接口
  • /*** 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 { }
  • 在 Spring 中有特別多類似這樣的標記接口的設計方式,它們的存在就像是一種標簽一樣,可以方便統一摘取出屬于此類接口的實現類,通常會有 instanceof 一起判斷使用。
  • 容器感知類
    • 3.1 BeanFactoryAware
    public interface BeanFactoryAware extends Aware {void setBeanFactory(BeanFactory beanFactory) throws BeansException; }
  • Interface to be implemented by beans that wish to be aware of theirowning {@link BeanFactory}.
  • 實現此接口,既能感知到所屬的 BeanFactory
    • 3.2 BeanClassLoaderAware
    public interface BeanClassLoaderAware extends Aware{void setBeanClassLoader(ClassLoader classLoader); }
  • Callback that allows a bean to be aware of the bean{@link ClassLoader class loader}; that is, the class loader used by the present beanfactory to load bean classes.
  • 實現此接口,既能感知到所屬的 ClassLoader
    • 3.3 BeanNameAware
    public interface BeanNameAware extends Aware {void setBeanName(String name); }
    • Interface to be implemented by beans that want to be aware of their bean name in a bean factory.
    • 實現此接口,既能感知到所屬的 BeanName

    3.4 ApplicationContextAware

    public interface ApplicationContextAware extends Aware {void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
    • Interface to be implemented by any object that wishes to be notified of the {@link ApplicationContext} that it runs in.
    • 實現此接口,既能感知到所屬的ApplicationContext
  • 包裝處理器(ApplicationContextAwareProcessor)
  • public class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ApplicationContext applicationContext;public ApplicationContextAwareProcessor(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ApplicationContextAware){((ApplicationContextAware) bean).setApplicationContext(applicationContext);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;} }
    • 由于 ApplicationContext 的獲取并不能直接在創建 Bean 時候就可以拿到,所以需要在 refresh 操作時,把ApplicationContext 寫入到一個包裝的 BeanPostProcessor 中去,由AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization方法調用。
  • 注冊 BeanPostProcessor
  • public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {@Overridepublic void refresh() throws BeansException {// 1. 創建 BeanFactory,并加載 BeanDefinitionrefreshBeanFactory();// 2. 獲取 BeanFactoryConfigurableListableBeanFactory beanFactory = getBeanFactory();// 3. 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對象都能感知所屬的 ApplicationContextbeanFactory.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();}// ... }

    refresh() 方法就是整個 Spring 容器的操作過程,與上一章節對比,本次新增加了關于 addBeanPostProcessor 的操作。添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對象都能感知所屬的 ApplicationContext。

  • 感知調用操作
  • public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();@Overrideprotected 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) {// invokeAwareMethodsif (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;}@Overridepublic 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;}@Overridepublic 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;} }
  • 這里我們去掉了一些類的內容,只保留關于本次 Aware 感知接口的操作。首先在 initializeBean 中,通過判斷 bean
    instanceof Aware,調用了三個接口方法,
    • BeanFactoryAware.setBeanFactory(this)
    • BeanClassLoaderAware.setBeanClassLoader(getBeanClassLoader())、
    • BeanNameAware.setBeanName(beanName),

    這樣就能通知到已經實現了此接口的類。另外我們還向 BeanPostProcessor 中添加了ApplicationContextAwareProcessor,此時在這個方法中也會被調用到具體的類實現,得到一個ApplicationContex 屬性。

    四、測試

  • 事先準備
  • 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);} } 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;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {System.out.println("Bean Name is:" + name);}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("ClassLoader:" + classLoader);}// ...get/set }
    • UserDao 本次并沒有什么改變,還是提供了關于初始化的方法,并在 Spring.xml 中提供init-method、destroy-method 配置信息。
    • UserService 新增加,BeanNameAware,BeanClassLoaderAware, ApplicationContextAware,BeanFactoryAware,四個感知的實現類,并在類中實現相應的接口方法。
  • 配置文件
    基礎配置,無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>

    五、總結

    目前關于 Spring 框架的實現中,某些功能點已經越來趨向于完整,尤其是 Bean 對象的生命周期,已經有了很多的體現。整體總結如圖

  • 本章節關于 Aware 的感知接口的四個繼承接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 的實現,又擴展了 Spring 的功能。如果你有做過關于 Spring中間件的開發那么一定會大量用到這些類,現在你不只是用過,而且還知道他們都是什么時候觸達的,在以后想排查類的實例化順序也可以有一個清晰的思路了。
  • 每一章節內容的實現都是在以設計模式為核心的結構上填充各項模塊的功能,單純的操作編寫代碼并不會有太多收獲,一定是要理解為什么這么設計,這么設計的好處是什么,怎么就那么多接口和抽象類的應用,這些才是Spring 框架學習的核心所在。
  • 總結

    以上是生活随笔為你收集整理的手写简版spring --8--Aware感知容器对象Aware感知容器对象的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。