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

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

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

前篇回顧:

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

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

register方法

到上面位為止,AnnotationConfigApplicationContext構(gòu)造函數(shù)執(zhí)行完畢,調(diào)用register方法注冊(cè)配置類,實(shí)際執(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);
    //判斷這個(gè)類是否需要解析,主要根據(jù)注解進(jìn)行判斷
    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);
  }

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

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

這里最終將beanDefinition注冊(cè)給了之前實(shí)例化的beanFactorybeanFactory的實(shí)現(xiàn)類為DefaultListableBeanFactory。

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

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

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

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

refresh 方法

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

1、prepareRefresh

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

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

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

2、obtainFreshBeanFactory

返回我們之前創(chuàng)建好的DefaultListableBeanFactory實(shí)例beanFactory,這里使用的是它的接口ConfigurableListableBeanFactory來進(jìn)行接收。

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

這里進(jìn)行一下補(bǔ)充,如果是基于xml的配置,那么是在obtainFreshBeanFactory方法中初始化BeanFactory工廠的,并進(jìn)行bean的加載與注冊(cè),這里不再贅述。

3、prepareBeanFactory

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

  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    //bean表達(dá)式的解釋器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //bean對(duì)象與String類型的轉(zhuǎn)換,例如<property ref="dao">
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));    
    //spring核心代碼,添加一個(gè)后置管理器
    //能在bean中獲得到各種的*Aware
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //添加了自動(dòng)注入的忽略列表
    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);

    //添加一個(gè)用于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
    * 則注冊(cè)兩個(gè)bean,key為“systemProperties”和“systemEnvironment”,Value為Map
    * 這兩個(gè)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中維護(hù)了一個(gè)spring后置處理器的列表:

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

最終調(diào)用的是List的add方法,將后置處理器添加到列表的尾部:

this.beanPostProcessors.add(beanPostProcessor);

這里有必要簡單的對(duì)BeanPostProcessor進(jìn)行一下說明:

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這個(gè)后置處理器,可以讓我們?nèi)ゲ迨謆ean的初始化過程。

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

4、postProcessBeanFactory

postProcessBeanFactory是一個(gè)空的方法,沒有任何實(shí)現(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) {
}

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

5、invokeBeanFactoryPostProcessors

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

這個(gè)需要注意的是getBeanFactoryPostProcessors方法,這個(gè)方法是獲取手動(dòng)注冊(cè)給spring添加的BeanFactoryPostProcessor,這個(gè)“手動(dòng)注冊(cè)”并不是說寫好了以后添加一個(gè)@Component注解就可以了,因?yàn)槿绻恿俗⒔膺€是spring自己去掃描得到的。

看一下getBeanFactoryPostProcessors方法,就可以知道是這里直接返回了一個(gè)List:

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

而通過 AnnotationConfigApplicationContextaddBeanFactoryPostProcessor方法進(jìn)行添加,則直接添加進(jìn)了這個(gè)list中:

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

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

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

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

在獲取到beanName后,通過bean工廠的getBean方法將其實(shí)例化,并添加到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中的實(shí)例,這個(gè)對(duì)象非常重要,會(huì)在后面講到:

回到上面的調(diào)用過程,我們知道這個(gè)Collection中現(xiàn)在只有一個(gè)對(duì)象,所以調(diào)用的是上面提到的 ConfigurationClassPostProcessor對(duì)象的 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) {
  //定義一個(gè)list,存放beanFactory中的beanDefinition
  List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
  //獲取容器中注冊(cè)的所有beanDefinition的名字,目前有了7個(gè)
  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下面的這幾個(gè)注解就不再判斷了
    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個(gè)beanDefinition,然后去判斷是否加了以下注解:

@Configuration
@ComponentScan
@Import
@ImportResource

如果是,則添加到configCandidates的List中,運(yùn)行到這,可以看到在里面存了一個(gè)我們自定義的添加了@Configuration注解的類:

向下運(yùn)行,首先實(shí)例化了一個(gè)ConfigurationClassParser,用于解析各個(gè)配置類:

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

然后,實(shí)例化 2個(gè)Set,candidates 用于將之前加入的configCandidates進(jìn)行去重,因?yàn)橛锌赡苡卸鄠€(gè)配置類重復(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)

重點(diǎn)看一下doProcessConfigurationClass方法:

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

得到注解類的注解信息,例如basePackage等,存放在AnnotationAttributes中。之后對(duì)set進(jìn)行遍歷:

for (AnnotationAttributes componentScan : componentScans) {
  //掃描普通類,會(huì)掃描出來所有加了@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方法,實(shí)現(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) {
        //如果這個(gè)類是AbstractBeanDefinition的子類
        //則為他設(shè)置默認(rèn)值,比如lazy,init ,destroy
        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
      }
      if (candidate instanceof AnnotatedBeanDefinition) {
        //檢查并且處理常用的注解
        //這里的處理主要是指把常用注解的值設(shè)置到AnnotatedBeanDefinition當(dāng)中
        //當(dāng)前前提是這個(gè)類型必須是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類注解的類掃描出來,并生成對(duì)應(yīng)的beanDefinition,最后通過registerBeanDefinition方法,放入beanDefinitionMap中。

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

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

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

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

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

BeanDefinitionRegistryPostProcessor對(duì)BeanFactoryPostProcessor進(jìn)行了擴(kuò)展,添加了自己的方法。所以第一次執(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代理,并添加一個(gè)ImportAwareBeanPostProcessor后置處理器,這個(gè)后置處理器會(huì)在后面實(shí)例化bean的過程中用到。

6、registerBeanPostProcessors

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

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中找出所有實(shí)現(xiàn)BeanPostProcessor接口的類,并添加了一個(gè)BeanPostProcessorCheckerbeanFactory中,主要用于記錄信息。

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

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

對(duì)4個(gè)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是否已注冊(cè)過InstantiationAwareBeanPostProcessors
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    //beanFactory是否已注冊(cè)過DestructionAwareBeanPostProcessor
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    //將beanPostProcessor添加到beanPostProcessors中
    this.beanPostProcessors.add(beanPostProcessor);
  }

在這個(gè)方法中,如果beanPostProcessor已經(jīng)存在則移除,這樣做可以起到重排序的作用,如果beanPostProcessor原先在前面,經(jīng)過刪除后再添加,則變到最后面。到這,將所有實(shí)現(xiàn)了BeanPostProcessor接口的類加載到 BeanFactory 中。

7、非重點(diǎn)部分

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    一文徹底搞懂Java日期時(shí)間類詳解

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

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

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

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

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

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

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

    java中VO的使用解析

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

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

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

最新評(píng)論