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

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

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

      Spring BeanDefinition

      定義

      /**
       * A BeanDefinition describes a bean instance, which has property values,
       * constructor argument values, and further information supplied by
       * concrete implementations.
       *
       * <p>This is just a minimal interface: The main intention is to allow a
       * {@link BeanFactoryPostProcessor} to introspect and modify property values
       * and other bean metadata.
       *
       * @author Juergen Hoeller
       * @author Rob Harrop
       * @since 19.03.2004
       * @see ConfigurableListableBeanFactory#getBeanDefinition
       * @see org.springframework.beans.factory.support.RootBeanDefinition
       * @see org.springframework.beans.factory.support.ChildBeanDefinition
       */
      public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

      解讀:

      BeanDefinition相當于一個數據結構,Spring容器對bean的管理是通過BeanDefinition來實現的。

      方法

      BeanDefinition中的方法如下圖所示:

       

      類圖

      解讀:

      從上述類圖可以看到BeanDefinition有哪些實現類。

      AnnotatedBeanDefinition

      AnnotatedBeanDefinition的定義如下

      /**
       * Extended {@link org.springframework.beans.factory.config.BeanDefinition}
       * interface that exposes {@link org.springframework.core.type.AnnotationMetadata}
       * about its bean class - without requiring the class to be loaded yet.
       *
       * @author Juergen Hoeller
       * @since 2.5
       * @see AnnotatedGenericBeanDefinition
       * @see org.springframework.core.type.AnnotationMetadata
       */
      public interface AnnotatedBeanDefinition extends BeanDefinition {
      
          /**
           * Obtain the annotation metadata (as well as basic class metadata)
           * for this bean definition's bean class.
           * @return the annotation metadata object (never {@code null})
           */
          AnnotationMetadata getMetadata();
      
          /**
           * Obtain metadata for this bean definition's factory method, if any.
           * @return the factory method metadata, or {@code null} if none
           * @since 4.1.1
           */
          @Nullable
          MethodMetadata getFactoryMethodMetadata();
      
      }

      該類有如下幾個子類

      調用鏈路

      本部分準備探究一下Spring中解析bean的調用鏈路,涉及到幾個層次,譬如:ApplicationContext -> BeanDefinitionReader -> BeanDefinitionDocumentReader。

      可以帶著問題閱讀:

      • 這幾個層次之間是怎么關聯起來的?
      • 最終是如何解析bean的?

      ApplicationContext

      AbstractApplicationContext

          @Override
          public void refresh() throws BeansException, IllegalStateException {
              synchronized (this.startupShutdownMonitor) {
                  StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
      
                  // Prepare this context for refreshing.
                  prepareRefresh();
      
                  // Tell the subclass to refresh the internal bean factory.
                  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      
                  // Prepare the bean factory for use in this context.
                  prepareBeanFactory(beanFactory);
      
                  try {
                      // Allows post-processing of the bean factory in context subclasses.
                      postProcessBeanFactory(beanFactory);
      
                      StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                      // Invoke factory processors registered as beans in the context.
                      invokeBeanFactoryPostProcessors(beanFactory);
      
                      // Register bean processors that intercept bean creation.
                      registerBeanPostProcessors(beanFactory);
                      beanPostProcess.end();
      
                      // Initialize message source for this context.
                      initMessageSource();
      
                      // Initialize event multicaster for this context.
                      initApplicationEventMulticaster();
      
                      // Initialize other special beans in specific context subclasses.
                      onRefresh();
      
                      // Check for listener beans and register them.
                      registerListeners();
      
                      // Instantiate all remaining (non-lazy-init) singletons.
                      finishBeanFactoryInitialization(beanFactory);
      
                      // Last step: publish corresponding event.
                      finishRefresh();
                  }
      
                  catch (BeansException ex) {
                      if (logger.isWarnEnabled()) {
                          logger.warn("Exception encountered during context initialization - " +
                                  "cancelling refresh attempt: " + ex);
                      }
      
                      // Destroy already created singletons to avoid dangling resources.
                      destroyBeans();
      
                      // Reset 'active' flag.
                      cancelRefresh(ex);
      
                      // Propagate exception to caller.
                      throw ex;
                  }
      
                  finally {
                      // Reset common introspection caches in Spring's core, since we
                      // might not ever need metadata for singleton beans anymore...
                      resetCommonCaches();
                      contextRefresh.end();
                  }
              }
          }

       解讀:

      上述AbstractApplicationContext中的refresh方法調用的obtainFreshBeanFactory方法是整個調用鏈路的入口。

       

          /**
           * Tell the subclass to refresh the internal bean factory.
           * @return the fresh BeanFactory instance
           * @see #refreshBeanFactory()
           * @see #getBeanFactory()
           */
          protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
              refreshBeanFactory();
              return getBeanFactory();
          }

       

          /**
           * Subclasses must implement this method to perform the actual configuration load.
           * The method is invoked by {@link #refresh()} before any other initialization work.
           * <p>A subclass will either create a new bean factory and hold a reference to it,
           * or return a single BeanFactory instance that it holds. In the latter case, it will
           * usually throw an IllegalStateException if refreshing the context more than once.
           * @throws BeansException if initialization of the bean factory failed
           * @throws IllegalStateException if already initialized and multiple refresh
           * attempts are not supported
           */
          protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

      解讀:

      此處refreshBeanFactory方法是抽象方法,由如下兩個子類實現:

      (1)GenericApplicationContext

      說明:

      在GenericApplicationContext中,refreshBeanFactory方法僅允許被調用一次(由AtomicBoolean類型變量refreshed控制)

      (2)AbstractRefreshableApplicationContext

          /**
           * This implementation performs an actual refresh of this context's underlying
           * bean factory, shutting down the previous bean factory (if any) and
           * initializing a fresh bean factory for the next phase of the context's lifecycle.
           */
          @Override
          protected final void refreshBeanFactory() throws BeansException {
              if (hasBeanFactory()) {
                  destroyBeans();
                  closeBeanFactory();
              }
              try {
                  DefaultListableBeanFactory beanFactory = createBeanFactory();
                  beanFactory.setSerializationId(getId());
                  customizeBeanFactory(beanFactory);
                  loadBeanDefinitions(beanFactory);
                  this.beanFactory = beanFactory;
              }
              catch (IOException ex) {
                  throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
              }
          }

       

          /**
           * Load bean definitions into the given bean factory, typically through
           * delegating to one or more bean definition readers.
           * @param beanFactory the bean factory to load bean definitions into
           * @throws BeansException if parsing of the bean definitions failed
           * @throws IOException if loading of bean definition files failed
           * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
           * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
           */
          protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
                  throws BeansException, IOException;

      解讀:

      此處loadBeanDefinitions方法是抽象方法,有如下幾個子類實現了該方法:

      補充:

      AbstractRefreshableConfigApplicationContext是AbstractRefreshableApplicationContext的子類,該類有如下幾個子類

      loadBeanDefinitions方法

      挑選AbstractXmlApplicationContext以查看loadBeanDefinitions方法的實現細節,代碼如下:

          /**
           * Loads the bean definitions via an XmlBeanDefinitionReader.
           * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
           * @see #initBeanDefinitionReader
           * @see #loadBeanDefinitions
           */
          @Override
          protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
              // Create a new XmlBeanDefinitionReader for the given BeanFactory.
              XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
      
              // Configure the bean definition reader with this context's
              // resource loading environment.
              beanDefinitionReader.setEnvironment(this.getEnvironment());
              beanDefinitionReader.setResourceLoader(this);
              beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
      
              // Allow a subclass to provide custom initialization of the reader,
              // then proceed with actually loading the bean definitions.
              initBeanDefinitionReader(beanDefinitionReader);
              loadBeanDefinitions(beanDefinitionReader);
          }

       

          /**
           * Load the bean definitions with the given XmlBeanDefinitionReader.
           * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
           * method; hence this method is just supposed to load and/or register bean definitions.
           * @param reader the XmlBeanDefinitionReader to use
           * @throws BeansException in case of bean registration errors
           * @throws IOException if the required XML document isn't found
           * @see #refreshBeanFactory
           * @see #getConfigLocations
           * @see #getResources
           * @see #getResourcePatternResolver
           */
          protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
              Resource[] configResources = getConfigResources();
              if (configResources != null) {
                  reader.loadBeanDefinitions(configResources);
              }
              String[] configLocations = getConfigLocations();
              if (configLocations != null) {
                  reader.loadBeanDefinitions(configLocations);
              }
          }

      解讀:

      上述loadBeanDefinitions方法最終是調用了AbstractBeanDefinitionReader中的loadBeanDefinitions方法,參數是數組類型。

      問題:此處loadBeanDefinitions方法的返回值為空,而reader是new出來的變量,reader做什么事情看似跟ApplicationContext沒啥關系啊。

      答案:實則不然,構造reader時傳遞了beanFactory,在最終解析bean時用到了該參數,所以說beanfactory承擔了關聯解析bean的幾個層次的作用。

      posted @ 2021-09-06 08:34  時空穿越者  閱讀(97)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久国产成人av蜜臀| 日韩乱码人妻无码中文字幕视频 | 野花社区www视频日本| 激情五月天一区二区三区| 日韩中文字幕高清有码| 99蜜桃在线观看免费视频网站| 国产精品免费中文字幕| 亚洲综合在线亚洲优优色| 亚洲AV蜜桃永久无码精品| 亚洲精品熟女一区二区 | 亚洲乱色一区二区三区丝袜| 久久高清超碰AV热热久久| 日韩成人无码影院| 蜜臀久久综合一本av| 国产欧美日韩免费看AⅤ视频| 小嫩批日出水无码视频免费 | 精品少妇av蜜臀av| 无码av波多野结衣| 国产午夜福利视频一区二区| 人成午夜免费大片| 99精品全国免费观看视频| 蜜桃av亚洲第一区二区| 亚洲小说乱欧美另类| 精品无码成人片一区二区98| 国产成人综合在线观看不卡| 国产精品福利一区二区三区| 日本亚洲欧洲无免费码在线| 亚洲精品麻豆一二三区| 亚洲成av人片色午夜乱码| 永久免费在线观看蜜桃视频| 免费人妻无码不卡中文18禁| 国产视频深夜在线观看| 国产亚洲精品久久久久久青梅| 九九热在线精品视频观看| 国产精品久久中文字幕| 成人亚洲综合av天堂| 亚洲中文字幕无码久久2020| 两个人免费完整高清视频| 国产精品自在线拍国产手机版| 国产成人综合在线观看不卡| 亚洲欧美综合精品成人导航|