欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?容器初始化?register?與?refresh方法

 更新時間:2022年07月07日 09:24:39   作者:??碼農(nóng)參上??  
這篇文章主要介紹了Spring?容器初始化?register?與?refresh方法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前篇回顧:

Spring源碼解析容器初始化構(gòu)造方法

在上一篇文章中,我們介紹完了AnnotationConfigApplicationContext的構(gòu)造方法,本文我們來詳細(xì)說說接下來要被調(diào)用的方法。

register方法

到上面位為止,AnnotationConfigApplicationContext構(gòu)造函數(shù)執(zhí)行完畢,調(diào)用register方法注冊配置類,實際執(zhí)行方法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);
    //判斷這個類是否需要解析,主要根據(jù)注解進行判斷
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    abd.setInstanceSupplier(instanceSupplier);
    //得到類的作用域
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //把類的作用域添加到數(shù)據(jù)結(jié)構(gòu)中
    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);
  }

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

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

這里最終將beanDefinition注冊給了之前實例化的beanFactory,beanFactory的實現(xiàn)類為DefaultListableBeanFactory。

到這,我們已經(jīng)有兩種方法將一個類轉(zhuǎn)化為BeanDefinition

1、通過RootBeanDefinition 的構(gòu)造方法

2、調(diào)用AnnotatedBeanDefinitionReaderregister方法

執(zhí)行完這一步后,可以看到我們的配置類也被放入了beanDefinitionMap,到這里,spring的工廠初始化工作就完成了。

refresh 方法

注冊完成后,調(diào)用核心方法refresh,初始化spring環(huán)境:

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加鎖的,這樣做是為了防止一個線程在執(zhí)行refresh時,其他線程執(zhí)行spring容器的啟動或銷毀操作。下面,我們開始分析一下其中重要的方法,重要的注釋會寫在代碼中。

1、prepareRefresh

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

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

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

2、obtainFreshBeanFactory

返回我們之前創(chuàng)建好的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

準(zhǔn)備bean工廠,對功能進行填充,例如配置了一些標(biāo)準(zhǔn)特征,比如上下文的加載器ClassLoaderpostProcessor后置處理器。

  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    //bean表達式的解釋器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //bean對象與String類型的轉(zhuǎn)換,例如<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就是一些系統(tǒng)配置和系統(tǒng)環(huán)境信息
    * */
    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<>();

最終調(diào)用的是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在類的初始化之前執(zhí)行,postProcessAfterInitialization在類的初始化之后執(zhí)行。也就是說spring通過暴露出BeanPostProcessor這個后置處理器,可以讓我們?nèi)ゲ迨謆ean的初始化過程。

ApplicationContextAwareProcessor實現(xiàn)了這個接口,通過它spring向外暴露了上下文環(huán)境ApplicationContext,供我們調(diào)用。

4、postProcessBeanFactory

postProcessBeanFactory是一個空的方法,沒有任何實現(xiàn):

  /**
   * 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) {
}

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

5、invokeBeanFactoryPostProcessors

在該方法中,執(zhí)行已被注冊的BeanFactoryPostProcessor。BeanFactoryPostProcessor也是spring提供的擴展點之一,它運行于spring容器加載了beanDefinition之后,但還未實例化bean之前執(zhí)行。通過實現(xiàn)這個接口,可以在bean創(chuàng)建之前修改beanDefinition的屬性,并且可以同時配置多個BeanFactoryProcessor,通過設(shè)置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);
  }

回到代碼中,調(diào)用執(zhí)行了PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors 方法,這個方法用于執(zhí)行所有注冊的BeanFactoryPostProcessor。該方法中,創(chuàng)建一個List存放spring內(nèi)部自己實現(xiàn)了BeanDefinitionRegistryPostProcessor接口的對象,并從beanFactory中獲取這個type的bean的名稱:

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

此處,我們可以得到一個對應(yīng)的beanName

在獲取到beanName后,通過bean工廠的getBean方法將其實例化,并添加到currentRegistryProcessors中,然后調(diào)用invokeBeanDefinitionRegistryPostProcessors方法,執(zhí)行所有的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中的實例,這個對象非常重要,會在后面講到:

回到上面的調(diào)用過程,我們知道這個Collection中現(xiàn)在只有一個對象,所以調(diào)用的是上面提到的 ConfigurationClassPostProcessor對象的 postProcessBeanDefinitionRegistry方法:

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

最終調(diào)用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,則意味著已經(jīng)處理過了,直接跳過
      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進行去重,因為有可能有多個配置類重復(fù)了。alreadyParsed 用于判斷是否處理過,避免重復(fù)。

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

調(diào)用ConfigurationClassParserparse方法:

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

parse方法調(diào)用鏈較長,這里只列出其調(diào)用過程和重要掃描過程:

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當(dāng)中
  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());
    }
  }
}

這里的關(guān)鍵還是parse方法,調(diào)用ComponentScanAnnotationParser 的parse方法,然后調(diào)用ClassPathBeanDefinitionScannerdoScan方法,實現(xiàn)掃描核心功能:

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文件
    //并把它轉(zhuǎn)成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
      //先設(shè)置默認(rèn)值
      if (candidate instanceof AbstractBeanDefinition) {
        //如果這個類是AbstractBeanDefinition的子類
        //則為他設(shè)置默認(rèn)值,比如lazy,init ,destroy
        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
      }
      if (candidate instanceof AnnotatedBeanDefinition) {
        //檢查并且處理常用的注解
        //這里的處理主要是指把常用注解的值設(shè)置到AnnotatedBeanDefinition當(dāng)中
        //當(dāng)前前提是這個類型必須是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當(dāng)中
        registerBeanDefinition(definitionHolder, this.registry);
      }
    }
  }
  return beanDefinitions;
}

到這,spring已經(jīng)把所有加了@Component類注解的類掃描出來,并生成對應(yīng)的beanDefinition,最后通過registerBeanDefinition方法,放入beanDefinitionMap中。

到這,我們執(zhí)行完了ConfigurationClassPostProcessorinvokeBeanDefinitionRegistryPostProcessors方法。

回到PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法中繼續(xù)向下執(zhí)行:

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

第二行語句用于執(zhí)行我們自定義的beanFactoryPostProcessor,由于現(xiàn)在不存在,可以直接忽略,重點看第一條。

有的同學(xué)可能會問,剛才不是執(zhí)行了一條差不多的語句嗎,而且這個registryProcessors里面的東西也沒有變,還是ConfigurationClassPostProcessor,那么為什么要執(zhí)行兩遍?看一下繼承關(guān)系:

BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor進行了擴展,添加了自己的方法。所以第一次執(zhí)行的是:

BeanDefinitionRegistryPostProcessor # postProcessBeanDefinitionRegistry

而第二次執(zhí)行的方法是:

BeanFactoryPostProcessor # postProcessBeanFactory

這里調(diào)用了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配置類產(chǎn)生cglib代理,并添加一個ImportAwareBeanPostProcessor后置處理器,這個后置處理器會在后面實例化bean的過程中用到。

6、registerBeanPostProcessors

這一步用于向spring環(huán)境中注冊BeanPostProcessors后置處理器,前面說過,BeanPostProcessors的作用是在bean初始化的時候允許我們?nèi)斯みM行插手,當(dāng)然這里只是進行一個注冊的過程,并不會實際執(zhí)行,具體的執(zhí)行是bean在初始化的時候。

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

調(diào)用registerBeanPostProcessors方法:

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

首先從BeanDefinitionMap中找出所有實現(xiàn)BeanPostProcessor接口的類,并添加了一個BeanPostProcessorCheckerbeanFactory中,主要用于記錄信息。

然后,創(chuàng)建了4個List用于緩存不同類型的后置處理器:

//存放實現(xiàn)PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//存放Spring內(nèi)部的BeanPostProcesso
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//存放注冊實現(xiàn)Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
//存放常規(guī)的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();

對4個List分別調(diào)用PostProcessorRegistrationDelegateregisterBeanPostProcessors方法:

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

遍歷列表,調(diào)用AbstractBeanFactoryaddBeanPostProcessor方法,將后置處理器加到beanPostProcessors中:

 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果beanPostProcessor已經(jīng)存在則移除
    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已經(jīng)存在則移除,這樣做可以起到重排序的作用,如果beanPostProcessor原先在前面,經(jīng)過刪除后再添加,則變到最后面。到這,將所有實現(xiàn)了BeanPostProcessor接口的類加載到 BeanFactory 中。

7、非重點部分

以下部分是非重點部分,不需要過分關(guān)注,因此省略,只做一個大體的注釋說明:

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

到此這篇關(guān)于Spring 容器初始化 register 與 refresh方法的文章就介紹到這了,更多相關(guān)Spring register 與 refresh方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java面向?qū)ο蟮姆庋b特征深度解析

    Java面向?qū)ο蟮姆庋b特征深度解析

    在面向?qū)ο蟪淌皆O(shè)計方法中,封裝(英語:Encapsulation)是指一種將抽象性函式接口的實現(xiàn)細(xì)節(jié)部分包裝、隱藏起來的方法。封裝可以被認(rèn)為是一個保護屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機訪問
    2021-10-10
  • IDEA 2021配置JavaWeb項目超詳細(xì)教程

    IDEA 2021配置JavaWeb項目超詳細(xì)教程

    本文通過圖文并茂的形式給大家介紹IDEA 2021配置JavaWeb項目的過程,內(nèi)容簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • VsCode搭建Java開發(fā)環(huán)境的方法

    VsCode搭建Java開發(fā)環(huán)境的方法

    這篇文章主要介紹了VsCode搭建Java開發(fā)環(huán)境的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Java線程Timer定時器用法詳細(xì)總結(jié)

    Java線程Timer定時器用法詳細(xì)總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于Java線程Timer定時器用法詳細(xì)總結(jié)內(nèi)容,需要的朋友們學(xué)習(xí)下吧。
    2020-02-02
  • 一文徹底搞懂Java日期時間類詳解

    一文徹底搞懂Java日期時間類詳解

    這篇文章主要給大家介紹了關(guān)于Java日期時間類的相關(guān)資料,Calendar類的功能要比Date類強大很多,可以方便的進行日期的計算,獲取日期中的信息時考慮了時區(qū)等問題,需要的朋友可以參考下
    2023-10-10
  • MyBatis利用攔截器實現(xiàn)數(shù)據(jù)脫敏詳解

    MyBatis利用攔截器實現(xiàn)數(shù)據(jù)脫敏詳解

    現(xiàn)代網(wǎng)絡(luò)環(huán)境中,敏感數(shù)據(jù)的處理是至關(guān)重要的,敏感數(shù)據(jù)包括個人身份信息、銀行賬號、手機號碼等,所以本文主要為大家詳細(xì)介紹了MyBatis如何利用攔截器實現(xiàn)數(shù)據(jù)脫敏,希望對大家有所幫助
    2023-11-11
  • Spring Boot實現(xiàn)通用的接口參數(shù)校驗

    Spring Boot實現(xiàn)通用的接口參數(shù)校驗

    本文介紹基于 Spring Boot 和 JDK8 編寫一個 AOP ,結(jié)合自定義注解實現(xiàn)通用的接口參數(shù)校驗。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Spring Cloud重試機制與各組件的重試總結(jié)

    Spring Cloud重試機制與各組件的重試總結(jié)

    這篇文章主要給大家介紹了關(guān)于Spring Cloud中重試機制與各組件的重試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • java中VO的使用解析

    java中VO的使用解析

    這篇文章主要介紹了java中VO的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java數(shù)據(jù)結(jié)構(gòu)及算法實例:考拉茲猜想 Collatz Conjecture

    Java數(shù)據(jù)結(jié)構(gòu)及算法實例:考拉茲猜想 Collatz Conjecture

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)及算法實例:考拉茲猜想 Collatz Conjecture,本文直接給出實現(xiàn)代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下
    2015-06-06

最新評論