<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      手寫Spring框架-壹

      背景

      最近工作比較輕松,于是趁著手里沒有活,就打算自己寫一個簡單的Spring框架,因為之前背Spring的八股的時候老是背了就忘。
      --本來前面寫的好好的,也能勉強理解,但是到了第七章寫應用上下文時,一下子來了十多個接口和抽象類,直接就蒙了,于是打算畫圖幫助理解,并且寫博客記錄,防止以后又忘了。。

      參考

      小傅哥:https://bugstack.cn/md/spring/develop-spring/2021-05-16-第1章:開篇介紹,手寫Spring能給你帶來什么?.html

      因為前面第七章前面并不難,所以直接從第七章開始。
      首先介紹一下Bean的生命周期:

      1. 容器啟動階段

      加載配置(XML、注解、JavaConfig)

      解析成 BeanDefinition(class、scope、依賴等元信息)

      注冊到 BeanDefinitionRegistry

      2. BeanFactoryPostProcessor 階段

      觸發時機:在任何 Bean 實例化之前

      作用:修改 BeanDefinition 的元信息

      典型用途:占位符替換 ${}、動態修改屬性值等

      注意:此時 Bean 還沒有被創建。

      3. Bean 實例化階段

      Spring 調用構造方法 / 工廠方法,new 出對象。

      此時只是一個“空殼對象”,還沒有屬性。

      4. 屬性填充(依賴注入)

      Spring 根據 BeanDefinition 里的信息,進行 依賴注入:

      XML 里 配置的屬性注入

      構造器 / Setter 注入

      時機:實例化之后,初始化之前

      5. BeanPostProcessor 前置處理

      調用 postProcessBeforeInitialization(bean, beanName)

      在 Bean 初始化方法之前執行

      6. 初始化方法

      如果實現了 InitializingBean,執行 afterPropertiesSet()

      7. BeanPostProcessor 后置處理

      調用 postProcessAfterInitialization(bean, beanName)

      8. Bean 就緒

      現在 Bean 已經完全可用了,交給容器管理。

      正文

      本章的目標是實現滿足于在 Bean 對象從容器啟動到Bean可用的過程中執行用戶的自定義操作,但是如果只是添加這兩個接口,不做任何包裝,那么對于使用者來說還是非常麻煩的。我們希望于開發 Spring 的上下文操作類,把相應的 XML 加載 、注冊、實例化以及新增的修改和擴展都融合進去,讓 Spring 可以自動掃描到我們的新增服務,便于用戶使用。
      image

      提供給用戶的擴展接口

      首先是BeanFactoryPostProcessor接口,該接口是spring提供給用戶使用的接口,用戶實現該接口就可以在Bean實例化之前使用BeanFactory對Bean的注冊信息進行操作。
      注意:此時 Bean 還沒被創建。

      public interface BeanFactoryPostProcessor {
          /**
           * 在所有的 BeanDefinition 加載完成后,實例化 Bean 對象之前,提供修改 BeanDefinition 屬性的機制
           *
           * @param beanFactory
           * @throws BeansException
           */
          void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
      }
      

      然后是實現BeanPostProcessor接口,該接口是spring提供給用戶使用的接口,用戶通過實現該接口,就可以在Bean初始化前后對Bean進行操作。

      public interface BeanPostProcessor {
          /**
           * 在 Bean 對象執行初始化方法之前,執行此方法
           *
           * @param bean
           * @param beanName
           * @return
           * @throws BeansException
           */
          Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
      
          /**
           * 在 Bean 對象執行初始化方法之后,執行此方法
           *
           * @param bean
           * @param beanName
           * @return
           * @throws BeansException
           */
          Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
      }
      

      Spring內部使用的接口

      上面講的是Spring提供給用戶使用的接口,而spring內部也得有相關的定義,才能支持這種擴展

      ListableBeanFactory接口

      該接口的作用是可以獲取IOC容器里的多個Bean,是對BeanFactory的擴展,BeanFactory一次只能獲取一個Bean

      public interface ListableBeanFactory extends BeanFactory{
          /**
           * 按照類型返回 Bean 實例
           * @param type
           * @param <T>
           * @return
           * @throws BeansException
           */
          <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
      
          /**
           * Return the names of all beans defined in this registry.
           *
           * 返回注冊表中所有的Bean名稱
           */
          String[] getBeanDefinitionNames();
      }
      

      HierarchicalBeanFactory接口

      這是一個標記性接口,定義了spring容器分層的概念

      public interface HierarchicalBeanFactory extends BeanFactory {
      }
      

      AutowireCapableBeanFactory接口

      這個接口很容易與前面的BeanPostFactory接口混淆,這個接口是Spring內部使用的!!!
      繼承BeanFactory接口是需要獲得getBean的能力,它本身提供了兩個方法,用于在Bean初始化前后

      public interface AutowireCapableBeanFactory extends BeanFactory {
      
          /**
           * 執行 BeanPostProcessors 接口實現類的 postProcessBeforeInitialization 方法
           * 在Bean初始化之前執行一些操作-BeforeInitialization
           *
           * @param existingBean
           * @param beanName
           * @return
           * @throws BeansException
           */
          Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;
      
          /**
           * 執行 BeanPostProcessors 接口實現類的 postProcessorsAfterInitialization 方法
           * 在Bean初始化之后執行一些操作-AfterInitialization
           *
           * @param existingBean
           * @param beanName
           * @return
           * @throws BeansException
           */
          Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;
      }
      

      ConfigurableBeanFactory接口

      繼承HierarchicalBeanFactory代表支持容器分層的能力
      繼承SingletonBeanRegistry代表有獲取單例Bean的能力
      它的功能是在BeanFactory基礎上,一個支持父子容器、單例緩存并且可以有生命周期擴展(BeanPostProcessor-Bean初始化前后擴展處理的能力)
      并且具有保存和管理 BeanPostProcessor 列表的能力,定義了addBeanPostProcessor()方法

      public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
      
          /**
           * 兩種作用域
           */
          String SCOPE_SINGLETON = "singleton";
      
          String SCOPE_PROTOTYPE = "prototype";
      
          void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
      }
      

      ConfigurableListableBeanFactory接口

      這個接口非常重要,它繼承了ListableBeanFactory(支持一次獲取多個Bean的能力)、AutowireCapableBeanFactory(支持自動注入能力-創建和裝配Bean)、
      ConfigurableBeanFactory(支持作用域、配置、Bean初始化前后擴展的能力)
      這代表了這個接口能夠完整實現IOC容器的所有職責,實現了它就代表了是一個完整Spring容器!!!

      public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
          BeanDefinition getBeanDefinition(String beanName) throws BeansException;
      
          void preInstantiateSingletons() throws BeansException;
      }
      

      到了這里,Spring內部管理Bean實例的接口就創建好了,接下來創建上下文相關接口
      ApplicationContext是對外的接口,給用戶使用的,所以得繼承ListableBeanFactory來獲得對Bean的查詢能力,方便用戶獲取Bean。
      問題:為什么不繼承其他繼承了BeanFactory的接口,比如ConfigurableBeanFactory,它也有這些功能?
      解答:還是上面那句話,ApplicationContext是給用戶使用的,而ConfigurableBeanFactory是給容器內部使用的

      ApplicationContext接口

      public interface ApplicationContext extends ListableBeanFactory {
      }
      

      ConfigurableApplicationContext接口

      refresh()是spring容器的核心啟動方法
      這也是給spring內部容器使用的,所以單獨創建了它,而不是在ApplicationContext里定義refresh()方法

      public interface ConfigurableApplicationContext extends ApplicationContext{
      
          /**
           * 刷新容器
           * @throws BeansException
           */
          void refresh() throws BeansException;
      }
      

      AbstractApplicationContext抽象類

      該抽象類用模板方法模式實現了refresh()方法邏輯
      并且繼承了DefaultResourceLoader來獲得加載資源的能力,因為refresh()需要解析xml文件加載Bean

      public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
          @Override
          public void refresh() throws BeansException {
              // 1. 創建 BeanFactory,并加載 BeanDefinition
              refreshBeanFactory();
      
              // 2. 獲取 BeanFactory
              ConfigurableListableBeanFactory beanFactory = getBeanFactory();
      
              // 3. 在 Bean 實例化之前,執行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.)
              // 真正執行了
              invokeBeanFactoryPostProcessors(beanFactory);
      
              // 4. BeanPostProcessor 需要提前于其他 Bean 對象實例化之前執行注冊操作
              // 只是注冊,加入到執行鏈中,并沒有執行
              registerBeanPostProcessors(beanFactory);
      
              // 5. 提前實例化單例Bean對象
              beanFactory.preInstantiateSingletons();
          }
      
          /**
           * 獲取所有實現了BeanPostProcessor的Bean,將它加到BeanPostProcessor執行鏈,getBeansOfType()返回的就是beanDefinitionMap的遍歷順序,也就是注冊順序
           * 即BeanPostProcessor執行鏈里執行的順序是它的注冊順序
           * 如果需要改變執行的優先級,可以實現 PriorityOrdered 或 Ordered 接口
           * @param beanFactory
           */
          private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
              Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
              for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
                  beanFactory.addBeanPostProcessor(beanPostProcessor);
              }
          }
      
          /**
           * 直接執行了BeanFactoryProcessor
           * @param beanFactory
           */
          private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
              Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
              for (BeanFactoryPostProcessor beanFactoryPostProcessor:beanFactoryPostProcessorMap.values()){
                  beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
              }
          }
      
          /**
           * 門面+委托模式的應用,在這里再次實現getBeansOfType只是因為ApplicationContext是對用戶使用的,
           * 這里再次實現只是提供一個門面,但是真正實現還是委托給DefaultListableBeanFactory去做
           * @param type
           * @return
           * @param <T>
           * @throws BeansException
           */
          @Override
          public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
              return getBeanFactory().getBeansOfType(type);
          }
      
          @Override
          public String[] getBeanDefinitionNames() {
              return getBeanFactory().getBeanDefinitionNames();
          }
      
          @Override
          public Object getBean(String beanName) {
              return getBeanFactory().getBean(beanName);
          }
      
          @Override
          public Object getBean(String beanName, Object... args) {
              return getBeanFactory().getBean(beanName, args);
          }
      
          @Override
          public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
              return getBeanFactory().getBean(name, requiredType);
          }
      
          protected abstract void refreshBeanFactory() throws BeansException;
      
          protected abstract ConfigurableListableBeanFactory getBeanFactory();
      }
      

      AbstractRefreshableApplicationContext抽象類

      實現了父類AbstractApplicationContext的refreshBeanFactory()和getBeanFactory()方法
      分擔了父類AbstractApplicationContext的解析xml文件并創建beanFactory的職責
      自己實現了創建beanFactory的功能
      并且定義了抽象方法loadBeanDefinitions將解析xml文件的職責下發給子類

      public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext{
          private DefaultListableBeanFactory beanFactory;
      
          @Override
          protected void refreshBeanFactory() throws BeansException {
              DefaultListableBeanFactory beanFactory = createBeanFactory();
              loadBeanDefinitions(beanFactory);
              this.beanFactory = beanFactory;
          }
      
          protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory);
      
          private DefaultListableBeanFactory createBeanFactory() {
              return new DefaultListableBeanFactory();
          }
      
          @Override
          protected ConfigurableListableBeanFactory getBeanFactory() {
              return this.beanFactory;
          }
      }
      

      AbstractXmlApplicationContext抽象類

      負責解析配置文件并注冊Bean的功能
      定義抽象方法getConfigLocations()將獲取配置文件的職責下發

      public abstract class AbstractXmlApplicationContext extends AbstractRefreshableApplicationContext{
          @Override
          protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
              XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(this, beanFactory);
              String[] configLocations = getConfigLocations();
              if(null != configLocations && configLocations.length > 0) {
                  xmlBeanDefinitionReader.loadBeanDefinitions(configLocations);
              }
          }
      
          protected abstract String[] getConfigLocations();
      }
      

      ClassPathXmlApplicationContext抽象類

      負責獲取xml文件
      ClassPathXmlApplicationContext是這條繼承鏈的終點,也是spring容器啟動的起點
      通過調用refresh()來啟動容器

      public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
          private String[] configLocations;
      
          public ClassPathXmlApplicationContext() {}
      
          public ClassPathXmlApplicationContext(String configLocation) {
              this(new String[]{configLocation});
          }
      
          public ClassPathXmlApplicationContext(String[] configLocations) {
              this.configLocations = configLocations;
              //開啟容器啟動流程
              refresh();
          }
      
          @Override
          protected String[] getConfigLocations() {
              return configLocations;
          }
      }
      

      spring容器內部在哪擴展?

      BeanFactoryPostProcessor在AbstractApplicationContext抽象類的refresh()方法里直接執行,
      而BeanPostProcessor只是在這里把所有實現了BeanPostProcessor的接口加入到BeanPostProcessor執行鏈。
      而真正執行BeanPostProcessor是在Bean實例化之后,初始化前后,也就是AbstractAutowireCapableBeanFactory的createBean方法初始化前后

      目前第七章的架構圖

      spring架構圖.drawio

      posted @ 2025-08-29 17:03  憂傷丶情語  閱讀(7)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成av人片无码迅雷下载| 国产精品综合色区av| 日韩AV高清在线看片| 1区2区3区4区产品不卡码网站| 少妇夜夜春夜夜爽试看视频| 国产电影无码午夜在线播放| 亚洲国产成熟视频在线多多| 日本中文字幕不卡在线一区二区| 国产麻豆md传媒视频| 日韩精品一区二区三区日韩| 午夜成人无码免费看网站| 亚洲一区二区偷拍精品| 香蕉亚洲欧洲在线一区| 在线看免费无码av天堂| 国产人妻大战黑人20p| 欧美zoozzooz性欧美| 亚洲成aⅴ人在线电影| 浙江省| 亚洲第一狼人天堂网伊人| 亚洲人成网线在线播放VA| 亚洲卡1卡2卡新区网站| 亚洲男人的天堂网站| 国产mv在线天堂mv免费观看| 亚洲日韩成人无码不卡网站| 少妇粗大进出白浆嘿嘿视频| 91精品国产午夜福利| 午夜国产小视频| 六十路老熟妇乱子伦视频| 精品久久久久久无码不卡| 无码精品国产va在线观看| 99久久亚洲精品无码毛片| 综合久青草视频在线观看| 妺妺窝人体色www看美女| 国产精品国产高清国产av| 中文字幕无码乱码人妻系列蜜桃| 激情在线一区二区三区视频| 午夜高清福利在线观看| 久久亚洲AV成人网站玖玖| 日韩人妻少妇一区二区三区| 午夜福利偷拍国语对白| 国产乱码精品一区二区三|