Spring 容器初始化 register 與 refresh方法

前篇回顧:

Spring源碼解析容器初始化構造方法

在上一篇文章中,我們介紹完瞭AnnotationConfigApplicationContext的構造方法,本文我們來詳細說說接下來要被調用的方法。

register方法

到上面位為止,AnnotationConfigApplicationContext構造函數執行完畢,調用register方法註冊配置類,實際執行方法doRegisterBean

  <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    //判斷這個類是否需要解析,主要根據註解進行判斷
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    abd.setInstanceSupplier(instanceSupplier);
    //得到類的作用域
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //把類的作用域添加到數據結構中
    abd.setScope(scopeMetadata.getScopeName());
    //生成類的名字,通過beanNameGenerator
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
        if (Primary.class == qualifier) {
          abd.setPrimary(true);
        }
        else if (Lazy.class == qualifier) {
          abd.setLazyInit(true);
        }
        else {
          abd.addQualifier(new AutowireCandidateQualifier(qualifier));
        }
      }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
    }
  
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }

在上面這段代碼中,主要完成這幾項任務:

  • 首先根據我們傳入的類創建一個AnnotatedGenericBeanDefinition,它可以理解為一個數據結構,其中包含瞭類的一些元信息,例如作用域scope,懶加載lazy等屬性。
  • 調用processCommonDefinitionAnnotations方法,處理類中的通用註解,分析源碼得知處理瞭Lazy,DependsOn,Primary,Role等註解,處理完成後把它們添加到數據結構中。
  • 封裝成BeanDefinitionHolderBeanDefinitionHolder可以簡單的理解為一個Map,它關聯BeanDefinitionbeanName
  • 調用registerBeanDefinition方法,將上面的BeanDefinitionHolder註冊給registry,這個registry就是 AnnotationConfigApplicationContext,即BeanDefinitionRegistry
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
  }

這裡最終將beanDefinition註冊給瞭之前實例化的beanFactorybeanFactory的實現類為DefaultListableBeanFactory

到這,我們已經有兩種方法將一個類轉化為BeanDefinition

1、通過RootBeanDefinition 的構造方法

2、調用AnnotatedBeanDefinitionReaderregister方法

執行完這一步後,可以看到我們的配置類也被放入瞭beanDefinitionMap,到這裡,spring的工廠初始化工作就完成瞭。

refresh 方法

註冊完成後,調用核心方法refresh初始化spring環境:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      prepareRefresh();
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      prepareBeanFactory(beanFactory);
      try {
        postProcessBeanFactory(beanFactory);
        invokeBeanFactoryPostProcessors(beanFactory);
        registerBeanPostProcessors(beanFactory);
        initMessageSource();
        initApplicationEventMulticaster();
        onRefresh();
        registerListeners();
        finishBeanFactoryInitialization(beanFactory);
        finishRefresh();
      }
  ...
}

首先可以看到,方法中的代碼是被synchronized加鎖的,這樣做是為瞭防止一個線程在執行refresh時,其他線程執行spring容器的啟動或銷毀操作。下面,我們開始分析一下其中重要的方法,重要的註釋會寫在代碼中。

1、prepareRefresh

prepareRefresh方法中為一些啟動的準備工作,包括記錄啟動時間,是否激活標識位,初始化屬性源配置等工作

protected void prepareRefresh() {
    // 記錄啟動時間
    this.startupDate = System.currentTimeMillis();
    // closed 屬性設置為 false
    this.closed.set(false);
    //將 active 屬性設置為 true
    //上面兩個都是 AtomicBoolean類型
    this.active.set(true);

    if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
    }
    //註解模式下此方法為空
    initPropertySources();
    getEnvironment().validateRequiredProperties();
     ...
  }

2、obtainFreshBeanFactory

返回我們之前創建好的DefaultListableBeanFactory實例beanFactory,這裡使用的是它的接口ConfigurableListableBeanFactory來進行接收。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
  }

這裡進行一下補充,如果是基於xml的配置,那麼是在obtainFreshBeanFactory方法中初始化BeanFactory工廠的,並進行bean的加載與註冊,這裡不再贅述。

3、prepareBeanFactory

準備bean工廠,對功能進行填充,例如配置瞭一些標準特征,比如上下文的加載器ClassLoaderpostProcessor後置處理器。

  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    //bean表達式的解釋器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //bean對象與String類型的轉換,例如<property ref="dao">
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));    
    //spring核心代碼,添加一個後置管理器
    //能在bean中獲得到各種的*Aware
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //添加瞭自動註入的忽略列表
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //添加一個用於ApplicationListener的bean從事件廣播器中添加或刪除的後置處理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    /*
    * 如果自定義的bean中沒有名為“systemProperties”和“systemEnvironment”的Bean
    * 則註冊兩個bean,key為“systemProperties”和“systemEnvironment”,Value為Map
    * 這兩個bean就是一些系統配置和系統環境信息
    * */
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

需要說明的是添加後置處理器addBeanPostProcessor方法,在beanFactory中維護瞭一個spring後置處理器的列表:

private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

最終調用的是List的add方法,將後置處理器添加到列表的尾部:

this.beanPostProcessors.add(beanPostProcessor);

這裡有必要簡單的對BeanPostProcessor進行一下說明:

public interface BeanPostProcessor {
  @Nullable
  default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
  @Nullable
  default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
}

postProcessBeforeInitialization在類的初始化之前執行,postProcessAfterInitialization在類的初始化之後執行。也就是說spring通過暴露出BeanPostProcessor這個後置處理器,可以讓我們去插手bean的初始化過程。

ApplicationContextAwareProcessor實現瞭這個接口,通過它spring向外暴露瞭上下文環境ApplicationContext,供我們調用。

4、postProcessBeanFactory

postProcessBeanFactory是一個空的方法,沒有任何實現:

  /**
   * Modify the application context's internal bean factory after its standard
   * initialization. All bean definitions will have been loaded, but no beans
   * will have been instantiated yet. This allows for registering special
   * BeanPostProcessors etc in certain ApplicationContext implementations.
   * @param beanFactory the bean factory used by the application context
   */
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

看一下源碼中的註釋,可理解可以通過子類擴展當前類,添加一些BeanPostProcessor,在BeanDefinition被加載但bean還沒有實例化前,執行這些特殊的後置管理器進行功能擴展。

5、invokeBeanFactoryPostProcessors

在該方法中,執行已被註冊的BeanFactoryPostProcessorBeanFactoryPostProcessor也是spring提供的擴展點之一,它運行於spring容器加載瞭beanDefinition之後,但還未實例化bean之前執行。通過實現這個接口,可以在bean創建之前修改beanDefinition的屬性,並且可以同時配置多個BeanFactoryProcessor,通過設置order屬性來控制順序。

@FunctionalInterface
public interface BeanFactoryPostProcessor {
  void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

再來看看invokeBeanFactoryPostProcessors方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
  }

這個需要註意的是getBeanFactoryPostProcessors方法,這個方法是獲取手動註冊給spring添加的BeanFactoryPostProcessor,這個“手動註冊”並不是說寫好瞭以後添加一個@Component註解就可以瞭,因為如果加瞭註解還是spring自己去掃描得到的。

看一下getBeanFactoryPostProcessors方法,就可以知道是這裡直接返回瞭一個List:

  public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
  }

而通過 AnnotationConfigApplicationContextaddBeanFactoryPostProcessor方法進行添加,則直接添加進瞭這個list中:

public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
    this.beanFactoryPostProcessors.add(postProcessor);
  }

回到代碼中,調用執行瞭PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors 方法,這個方法用於執行所有註冊的BeanFactoryPostProcessor。該方法中,創建一個List存放spring內部自己實現瞭BeanDefinitionRegistryPostProcessor接口的對象,並從beanFactory中獲取這個type的bean的名稱:

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
          beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

此處,我們可以得到一個對應的beanName

在獲取到beanName後,通過bean工廠的getBean方法將其實例化,並添加到currentRegistryProcessors中,然後調用invokeBeanDefinitionRegistryPostProcessors方法,執行所有的BeanDefinitionRegistryPostProcessor

for (String ppName : postProcessorNames) {
  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
  }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合並list
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清除list
currentRegistryProcessors.clear();

看一下currentRegistryProcessors中的實例,這個對象非常重要,會在後面講到:

回到上面的調用過程,我們知道這個Collection中現在隻有一個對象,所以調用的是上面提到的 ConfigurationClassPostProcessor對象的 postProcessBeanDefinitionRegistry方法:

private static void invokeBeanDefinitionRegistryPostProcessors(
      Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {      
      postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
  }

最終調用ConfigurationClassPostProcessorprocessConfigBeanDefinitions。先看方法的前半段:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
  //定義一個list,存放beanFactory中的beanDefinition
  List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
  //獲取容器中註冊的所有beanDefinition的名字,目前有瞭7個
  String[] candidateNames = registry.getBeanDefinitionNames();
  for (String beanName : candidateNames) {
    BeanDefinition beanDef = registry.getBeanDefinition(beanName);
    if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
        ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
      //如果BeanDefinition中的configurationClass的屬性為full或者lite,則意味著已經處理過瞭,直接跳過
      if (logger.isDebugEnabled()) {
        logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
      }
    }
    //判斷是否Configuration類,如果加瞭Configuration下面的這幾個註解就不再判斷瞭
    else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
      configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
    }
  }

  // Return immediately if no @Configuration classes were found
  if (configCandidates.isEmpty()) {
    return;
  }

這裡先讀取瞭BeanFactory中存放的7個beanDefinition,然後去判斷是否加瞭以下註解:

@Configuration
@ComponentScan
@Import
@ImportResource

如果是,則添加到configCandidates的List中,運行到這,可以看到在裡面存瞭一個我們自定義的添加瞭@Configuration註解的類:

向下運行,首先實例化瞭一個ConfigurationClassParser,用於解析各個配置類:

ConfigurationClassParser parser = new ConfigurationClassParser(
        this.metadataReaderFactory, this.problemReporter, this.environment,
        this.resourceLoader, this.componentScanBeanNameGenerator, registry);

然後,實例化 2個Set,candidates 用於將之前加入的configCandidates進行去重,因為有可能有多個配置類重復瞭。alreadyParsed 用於判斷是否處理過,避免重復。

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());

調用ConfigurationClassParserparse方法:

do {
     parser.parse(candidates);
     ...
}
while (!candidates.isEmpty());

parse方法調用鏈較長,這裡隻列出其調用過程和重要掃描過程:

ConfigurationClassParser 
# parse(Set<BeanDefinitionHolder> configCandidates)
# parse(AnnotationMetadata metadata, String beanName)
# processConfigurationClas(ConfigurationClass configClass)
# doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)

重點看一下doProcessConfigurationClass方法:

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
      sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

得到註解類的註解信息,例如basePackage等,存放在AnnotationAttributes中。之後對set進行遍歷:

for (AnnotationAttributes componentScan : componentScans) {
  //掃描普通類,會掃描出來所有加瞭@Component註解的類
  //並且把掃描出來的普通bean放到map當中
  Set<BeanDefinitionHolder> scannedBeanDefinitions =
      this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
  //這一步完成後掃描出來瞭所有類
  //檢查掃描出的類是否還有 @Configuration
  for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
    if (bdCand == null) {
      bdCand = holder.getBeanDefinition();
    }
    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
      parse(bdCand.getBeanClassName(), holder.getBeanName());
    }
  }
}

這裡的關鍵還是parse方法,調用ComponentScanAnnotationParser 的parse方法,然後調用ClassPathBeanDefinitionScannerdoScan方法,實現掃描核心功能:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
  Assert.notEmpty(basePackages, "At least one base package must be specified");
  Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
  for (String basePackage : basePackages) {
    //掃描basePackage路徑下的java文件
    //並把它轉成BeanDefinition類型
    Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

    for (BeanDefinition candidate : candidates) {
      //解析scope屬性
      ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
      candidate.setScope(scopeMetadata.getScopeName());
      String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

      //所有掃描出來的類 是 ScannedGenericBeanDefinition  ,符合AbstractBeanDefinition
      //先設置默認值
      if (candidate instanceof AbstractBeanDefinition) {
        //如果這個類是AbstractBeanDefinition的子類
        //則為他設置默認值,比如lazy,init ,destroy
        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
      }
      if (candidate instanceof AnnotatedBeanDefinition) {
        //檢查並且處理常用的註解
        //這裡的處理主要是指把常用註解的值設置到AnnotatedBeanDefinition當中
        //當前前提是這個類型必須是AnnotatedBeanDefinition類型的,也就是加瞭註解的類
        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
      }
      if (checkCandidate(beanName, candidate)) {
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
        definitionHolder =
            AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        beanDefinitions.add(definitionHolder);
        //加入到BeanDefinitionMap當中
        registerBeanDefinition(definitionHolder, this.registry);
      }
    }
  }
  return beanDefinitions;
}

到這,spring已經把所有加瞭@Component類註解的類掃描出來,並生成對應的beanDefinition,最後通過registerBeanDefinition方法,放入beanDefinitionMap中。

到這,我們執行完瞭ConfigurationClassPostProcessorinvokeBeanDefinitionRegistryPostProcessors方法。

回到PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法中繼續向下執行:

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

第二行語句用於執行我們自定義的beanFactoryPostProcessor,由於現在不存在,可以直接忽略,重點看第一條。

有的同學可能會問,剛才不是執行瞭一條差不多的語句嗎,而且這個registryProcessors裡面的東西也沒有變,還是ConfigurationClassPostProcessor,那麼為什麼要執行兩遍?看一下繼承關系:

BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor進行瞭擴展,添加瞭自己的方法。所以第一次執行的是:

BeanDefinitionRegistryPostProcessor # postProcessBeanDefinitionRegistry

而第二次執行的方法是:

BeanFactoryPostProcessor # postProcessBeanFactory

這裡調用瞭ConfigurationClassPostProcessorpostProcessBeanFactory方法:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    int factoryId = System.identityHashCode(beanFactory);
    if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
          "postProcessBeanFactory already called on this post-processor against " + beanFactory);
    }
    this.factoriesPostProcessed.add(factoryId);
    if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
    }
   
    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
  }

主要用於給我們的@Configuration配置類產生cglib代理,並添加一個ImportAwareBeanPostProcessor後置處理器,這個後置處理器會在後面實例化bean的過程中用到。

6、registerBeanPostProcessors

這一步用於向spring環境中註冊BeanPostProcessors後置處理器,前面說過,BeanPostProcessors的作用是在bean初始化的時候允許我們人工進行插手,當然這裡隻是進行一個註冊的過程,並不會實際執行,具體的執行是bean在初始化的時候。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

調用registerBeanPostProcessors方法:

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

首先從BeanDefinitionMap中找出所有實現BeanPostProcessor接口的類,並添加瞭一個BeanPostProcessorCheckerbeanFactory中,主要用於記錄信息。

然後,創建瞭4個List用於緩存不同類型的後置處理器:

//存放實現PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//存放Spring內部的BeanPostProcesso
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//存放註冊實現Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
//存放常規的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();

對4個List分別調用PostProcessorRegistrationDelegateregisterBeanPostProcessors方法:

private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
    }
  }

遍歷列表,調用AbstractBeanFactoryaddBeanPostProcessor方法,將後置處理器加到beanPostProcessors中:

 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果beanPostProcessor已經存在則移除
    this.beanPostProcessors.remove(beanPostProcessor);
    // beanFactory是否已註冊過InstantiationAwareBeanPostProcessors
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    //beanFactory是否已註冊過DestructionAwareBeanPostProcessor
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    //將beanPostProcessor添加到beanPostProcessors中
    this.beanPostProcessors.add(beanPostProcessor);
  }

在這個方法中,如果beanPostProcessor已經存在則移除,這樣做可以起到重排序的作用,如果beanPostProcessor原先在前面,經過刪除後再添加,則變到最後面。到這,將所有實現瞭BeanPostProcessor接口的類加載到 BeanFactory 中。

7、非重點部分

以下部分是非重點部分,不需要過分關註,因此省略,隻做一個大體的註釋說明:

//初始化上下文的 MessageSource源
initMessageSource();
//初始化應用事件廣播器
initApplicationEventMulticaster();
//空方法,可用做子類擴展
onRefresh();
//在所有註冊的bean中查找Listener bean,註冊到消息廣播器中
registerListeners();

到此這篇關於Spring 容器初始化 register 與 refresh方法的文章就介紹到這瞭,更多相關Spring register 與 refresh方法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: