Spring IoC源碼解析之invokeBeanFactoryPostProcessors

  • 2019 年 10 月 3 日
  • 筆記

一、Bean工廠的後置處理器

  Bean工廠的後置處理器:BeanFactoryPostProcessor(觸發時機:bean定義註冊之後bean實例化之前)和BeanDefinitionRegistryPostProcessor(觸發時機:bean定義註冊之前),所以可以在Bean工廠的後置處理器中修改Bean的定義資訊,比如是否延遲載入、加入一些新的Bean的定義資訊等

  Bean工廠的後置處理器類繼承圖:

二、調用Bean工廠的後置處理器

  invokeBeanFactoryPostProcessors(beanFactory)方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {          //傳入Bean工廠並獲取容器中的Bean工廠後置處理器(注意這裡Bean工廠後置處理器還沒有初始化)          PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());            // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime          // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)          if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {              beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));              beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));          }      }

  進入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法:

final class PostProcessorRegistrationDelegate {      public static void invokeBeanFactoryPostProcessors(              ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {            Set<String> processedBeans = new HashSet<>();            //判斷我們的beanFactory是否實現了BeanDefinitionRegistry          if (beanFactory instanceof BeanDefinitionRegistry) {              //強行把beanFactory轉為BeanDefinitionRegistry              BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;              //保存BeanFactoryPostProcessor類型的後置處理器              List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();              //保存BeanDefinitionRegistryPostProcessor類型的後置處理器              List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();                //循環我們傳遞進來的beanFactoryPostProcessors              for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {                  //判斷我們的後置處理器是不是BeanDefinitionRegistryPostProcessor                  if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                      //進行強制轉化                      BeanDefinitionRegistryPostProcessor registryProcessor =                              (BeanDefinitionRegistryPostProcessor) postProcessor;                      //調用它的後置方法                      registryProcessor.postProcessBeanDefinitionRegistry(registry);                      //添加到我們用於保存的BeanDefinitionRegistryPostProcessor的集合中                      registryProcessors.add(registryProcessor);                  }                  else {//若沒有實現BeanDefinitionRegistryPostProcessor介面,那麼他就是BeanFactoryPostProcessor 把當前的後置處理器加入到regularPostProcessors中                      regularPostProcessors.add(postProcessor);                  }              }                //定義一個集合用戶保存當前準備創建的BeanDefinitionRegistryPostProcessor              List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();                //第一步:去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱              String[] postProcessorNames =                      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);              //循環上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱              for (String ppName : postProcessorNames) {                  //判斷是否實現了PriorityOrdered介面的                  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                      //顯示的調用getBean()的方式獲取出該對象然後加入到currentRegistryProcessors集合中去                      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                      //同時也加入到processedBeans集合中去                      processedBeans.add(ppName);                  }              }              //對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序              sortPostProcessors(currentRegistryProcessors, beanFactory);              //把他加入到用於保存到registryProcessors中              registryProcessors.addAll(currentRegistryProcessors);              /**               * 在這裡典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor               * 用於進行bean定義的載入 比如我們的包掃描,@import等               */              invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);              //調用完之後,馬上clear              currentRegistryProcessors.clear();                //下一步 又去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱              postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);              //循環上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱              for (String ppName : postProcessorNames) {                  //表示沒有被處理過,且實現了Ordered介面的                  if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {                      //顯示的調用getBean()的方式獲取出該對象然後加入到currentRegistryProcessors集合中去                      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                      //同時也加入到processedBeans集合中去                      processedBeans.add(ppName);                  }              }              //對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序              sortPostProcessors(currentRegistryProcessors, beanFactory);              //把他加入到用於保存到registryProcessors中              registryProcessors.addAll(currentRegistryProcessors);              //調用他的後置處理方法              invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);              //調用完之後,馬上clear              currentRegistryProcessors.clear();                //調用沒有實現任何優先順序介面的BeanDefinitionRegistryPostProcessor              //定義一個重複處理的開關變數 默認值為true              boolean reiterate = true;              //第一次就可以進來              while (reiterate) {                  //進入循環馬上把開關變數給改為false                  reiterate = false;                  //去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱                  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);                  //循環上一步獲取的BeanDefinitionRegistryPostProcessor的類型名稱                  for (String ppName : postProcessorNames) {                      //沒有被處理過的                      if (!processedBeans.contains(ppName)) {                          //顯示的調用getBean()的方式獲取出該對象然後加入到currentRegistryProcessors集合中去                          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                          //同時也加入到processedBeans集合中去                          processedBeans.add(ppName);                          //再次設置為true                          reiterate = true;                      }                  }                  //對currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor進行排序                  sortPostProcessors(currentRegistryProcessors, beanFactory);                  //把他加入到用於保存到registryProcessors中                  registryProcessors.addAll(currentRegistryProcessors);                  //調用他的後置處理方法                  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);                  //進行clear                  currentRegistryProcessors.clear();              }                //調用實現了BeanDefinitionRegistryPostProcessor的介面 他是他也同時實現了BeanFactoryPostProcessor的方法              invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);              //調用BeanFactoryPostProcessor              invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);          }            else { //若當前的beanFactory沒有實現了BeanDefinitionRegistry 直接調用beanFactoryPostProcessor介面的方法進行後置處理              invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);          }            //最後一步 獲取容器中所有的 BeanFactoryPostProcessor          String[] postProcessorNames =                  beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);            //保存BeanFactoryPostProcessor類型實現了priorityOrdered          List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();          //保存BeanFactoryPostProcessor類型實現了Ordered介面的          List<String> orderedPostProcessorNames = new ArrayList<>();          //保存BeanFactoryPostProcessor沒有實現任何優先順序介面的          List<String> nonOrderedPostProcessorNames = new ArrayList<>();          for (String ppName : postProcessorNames) {              //processedBeans包含的話,表示在上面處理BeanDefinitionRegistryPostProcessor的時候處理過了              if (processedBeans.contains(ppName)) {                  // skip - already processed in first phase above              }              //判斷是否實現了PriorityOrdered              else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                  priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));              }              //判斷是否實現了Ordered              else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {                  orderedPostProcessorNames.add(ppName);              }              //沒有實現任何的優先順序介面的              else {                  nonOrderedPostProcessorNames.add(ppName);              }          }            //先調用BeanFactoryPostProcessor實現了PriorityOrdered介面的          sortPostProcessors(priorityOrderedPostProcessors, beanFactory);          invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);            //再調用BeanFactoryPostProcessor實現了Ordered.          List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();          for (String postProcessorName : orderedPostProcessorNames) {              orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));          }          sortPostProcessors(orderedPostProcessors, beanFactory);          invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);            //調用沒有實現任何方法介面的          List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();          for (String postProcessorName : nonOrderedPostProcessorNames) {              nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));          }          invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);            // Clear cached merged bean definitions since the post-processors might have          // modified the original metadata, e.g. replacing placeholders in values...          beanFactory.clearMetadataCache();      }

  第一步:去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱
  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)  Debug進去看到如下:為什麼就一個ConfigurationClassPostProcessor,因為我們自定的BeanDefinitionRegistryPostProcessor還沒有被加入到Spring容器中去

  第一步裡面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法:

/**       * Invoke the given BeanDefinitionRegistryPostProcessor beans.       */      private static void invokeBeanDefinitionRegistryPostProcessors(              Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {          //獲取容器中的ConfigurationClassPostProcessor的後置處理器進行Bean定義的掃描          for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {              postProcessor.postProcessBeanDefinitionRegistry(registry);          }      }

  接下來就會調用到org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法(很重要):

/**       * Derive further bean definitions from the configuration classes in the registry.       */      @Override      public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {          int registryId = System.identityHashCode(registry);          if (this.registriesPostProcessed.contains(registryId)) {              throw new IllegalStateException(                      "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);          }          if (this.factoriesPostProcessed.contains(registryId)) {              throw new IllegalStateException(                      "postProcessBeanFactory already called on this post-processor against " + registry);          }          this.registriesPostProcessed.add(registryId);          //真正的解析我們的Bean定義          processConfigBeanDefinitions(registry);      }

  進入到真正的解析processConfigBeanDefinitions方法中:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {          List<BeanDefinitionHolder> configCandidates = new ArrayList<>();          //獲取Spring IoC容器中目前所有Bean定義的名稱          String[] candidateNames = registry.getBeanDefinitionNames();            //循環所有的Bean定義資訊          for (String beanName : candidateNames) {              //通過Bean的名稱來獲取Bean的定義對象              BeanDefinition beanDef = registry.getBeanDefinition(beanName);              //判斷是否有沒有解析過              if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||                      ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {                  if (logger.isDebugEnabled()) {                      logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);                  }              }              //判斷是否是配置類              else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {                  //添加到候選的配置類集合中                  configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));              }          }            // 若沒有找到配置類 直接返回          if (configCandidates.isEmpty()) {              return;          }            //對我們的配置類進行Order排序          configCandidates.sort((bd1, bd2) -> {              int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());              int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());              return Integer.compare(i1, i2);          });            //創建@CompentScan、@Import導入進來的bean名稱的生成器          SingletonBeanRegistry sbr = null;          if (registry instanceof SingletonBeanRegistry) {              sbr = (SingletonBeanRegistry) registry;              if (!this.localBeanNameGeneratorSet) {                  BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);                  if (generator != null) {                      //設置@CompentScan導入進來的bean的名稱生成器                      this.componentScanBeanNameGenerator = generator;                      //設置@Import導入進來的bean的名稱生成器                      this.importBeanNameGenerator = generator;                  }              }          }            if (this.environment == null) {              this.environment = new StandardEnvironment();          }            //創建一個配置類解析器對象          ConfigurationClassParser parser = new ConfigurationClassParser(                  this.metadataReaderFactory, this.problemReporter, this.environment,                  this.resourceLoader, this.componentScanBeanNameGenerator, registry);            //創建一個集合用於保存我們的配置類BeanDefinitionHolder集合默認長度是配置類集合的長度          Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);          //創建一個集合用於保存我們的已經解析的配置類,長度默認為解析出來默認的配置類的集合長度          Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());          //do while          do {              //真正的解析我們的配置類              parser.parse(candidates);              parser.validate();                //解析出來的配置類              Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());              configClasses.removeAll(alreadyParsed);                // Read the model and create bean definitions based on its content              if (this.reader == null) {                  this.reader = new ConfigurationClassBeanDefinitionReader(                          registry, this.sourceExtractor, this.resourceLoader, this.environment,                          this.importBeanNameGenerator, parser.getImportRegistry());              }              //真正的把我們解析出來的配置類註冊到容器中              this.reader.loadBeanDefinitions(configClasses);              //加入到已經解析的集合中              alreadyParsed.addAll(configClasses);                candidates.clear();              //判斷我們Spring IoC容器中Bean的定義數量是否 > 候選原始的bean定義的個數              if (registry.getBeanDefinitionCount() > candidateNames.length) {                  //獲取所有的bean定義                  String[] newCandidateNames = registry.getBeanDefinitionNames();                  //原始的老的候選的bean定義                  Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));                  Set<String> alreadyParsedClasses = new HashSet<>();                  //賦值已經解析的                  for (ConfigurationClass configurationClass : alreadyParsed) {                      alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());                  }                    for (String candidateName : newCandidateNames) {                      //表示當前循環的還沒有被解析過                      if (!oldCandidateNames.contains(candidateName)) {                          BeanDefinition bd = registry.getBeanDefinition(candidateName);                          //判斷有沒有被解析過                          if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&                                  !alreadyParsedClasses.contains(bd.getBeanClassName())) {                              candidates.add(new BeanDefinitionHolder(bd, candidateName));                          }                      }                  }                  candidateNames = newCandidateNames;              }          }          //存在沒有解析過的 需要循環解析          while (!candidates.isEmpty());            // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes          if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {              sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());          }            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {              // Clear cache in externally provided MetadataReaderFactory; this is a no-op              // for a shared cache since it'll be cleared by the ApplicationContext.              ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();          }      }

  Debug解析:

  進入parser.parse(candidates)方法:

public void parse(Set<BeanDefinitionHolder> configCandidates) {          //用於保存延時的ImportSelectors          this.deferredImportSelectors = new LinkedList<>();            for (BeanDefinitionHolder holder : configCandidates) {              BeanDefinition bd = holder.getBeanDefinition();              try {                  //真正的解析我們的bean定義                  if (bd instanceof AnnotatedBeanDefinition) {                      parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());                  }                  else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {                      parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());                  }                  else {                      parse(bd.getBeanClassName(), holder.getBeanName());                  }              }              catch (BeanDefinitionStoreException ex) {                  throw ex;              }              catch (Throwable ex) {                  throw new BeanDefinitionStoreException(                          "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);              }          }          //處理我們延時的DeferredImportSelectors Spring Boot就是通過這步進行spring.factories文件中的自定裝配的對象          processDeferredImportSelectors();      }

  Debug解析:

  進入parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName())方法:

/**       * 真正的解析我們的配置類       * @param metadata 配置類的源資訊       * @param beanName 當前配置類的beanName       * @throws IOException       */      protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {          //把我們的配置類源資訊和beanName包裝成一個ConfigurationClass對象          processConfigurationClass(new ConfigurationClass(metadata, beanName));      }

  進入processConfigurationClass(new ConfigurationClass(metadata, beanName))方法:

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {          if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {              return;          }            //獲取我們的配置類對象          ConfigurationClass existingClass = this.configurationClasses.get(configClass);            if (existingClass != null) {              //傳入的配置類是通過其他配置類的Import導入進來的              if (configClass.isImported()) {                  if (existingClass.isImported()) {                      //需要合併配置                      existingClass.mergeImportedBy(configClass);                  }                  // Otherwise ignore new imported config class; existing non-imported class overrides it.                  return;              }              else {                  // Explicit bean definition found, probably replacing an import.                  // Let's remove the old one and go with the new one.                  this.configurationClasses.remove(configClass);                  this.knownSuperclasses.values().removeIf(configClass::equals);              }          }            // Recursively process the configuration class and its superclass hierarchy.          SourceClass sourceClass = asSourceClass(configClass);          //真正的進行配置類的解析          do {              //解析我們的配置類              sourceClass = doProcessConfigurationClass(configClass, sourceClass);          }          while (sourceClass != null);            this.configurationClasses.put(configClass, configClass);      }

  進入解析我們的配置類的doProcessConfigurationClass(configClass, sourceClass)方法:

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)              throws IOException {            // Recursively process any member (nested) classes first          processMemberClasses(configClass, sourceClass);            //處理我們的@PropertySources註解的          for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(                  sourceClass.getMetadata(), PropertySources.class,                  org.springframework.context.annotation.PropertySource.class)) {              if (this.environment instanceof ConfigurableEnvironment) {                  processPropertySource(propertySource);              }              else {                  logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +                          "]. Reason: Environment must implement ConfigurableEnvironment");              }          }            //接下來解析我們的@ComponentScans註解          //從我們的配置類上解析@ComponentScans的對象集合屬性          Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(                  sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);          if (!componentScans.isEmpty() &&                  !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {              //循環解析(我們解析出來的AnnotationAttributes)              for (AnnotationAttributes componentScan : componentScans) {                  //把我們掃描出來的類變為bean定義的集合                  Set<BeanDefinitionHolder> scannedBeanDefinitions =                          this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());                  //循環處理我們包掃描出來的bean定義                  for (BeanDefinitionHolder holder : scannedBeanDefinitions) {                      BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();                      if (bdCand == null) {                          bdCand = holder.getBeanDefinition();                      }                      //判斷當前掃描出來的bean定義是不是一個配置類,若是的話 直接進行遞歸解析                      if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {                          //遞歸解析                          parse(bdCand.getBeanClassName(), holder.getBeanName());                      }                  }              }          }            //處理@Import          processImports(configClass, sourceClass, getImports(sourceClass), true);            //處理@ImportResource          AnnotationAttributes importResource =                  AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);          if (importResource != null) {              String[] resources = importResource.getStringArray("locations");              Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");              for (String resource : resources) {                  String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);                  configClass.addImportedResource(resolvedResource, readerClass);              }          }            //處理@Bean methods獲取到我們配置類中所有標註了@Bean的方法          Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);            for (MethodMetadata methodMetadata : beanMethods) {              configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));          }            //處理配置類介面的          processInterfaces(configClass, sourceClass);            //處理配置類的父類的          if (sourceClass.getMetadata().hasSuperClass()) {              String superclass = sourceClass.getMetadata().getSuperClassName();              if (superclass != null && !superclass.startsWith("java") &&                      !this.knownSuperclasses.containsKey(superclass)) {                  this.knownSuperclasses.put(superclass, configClass);                  // Superclass found, return its annotation metadata and recurse                  return sourceClass.getSuperClass();              }          }            //沒有父類解析完成          return null;      }

  Debug解析:

  ① 解析@ComponentScanthis.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName())方法:

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {          ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,                  componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);            //給掃描器設置beanName的生成器對象          Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");          boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);          scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :                  BeanUtils.instantiateClass(generatorClass));            //設置bean的域代理模型          ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");          if (scopedProxyMode != ScopedProxyMode.DEFAULT) {              scanner.setScopedProxyMode(scopedProxyMode);          }          else {              Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");              scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));          }            scanner.setResourcePattern(componentScan.getString("resourcePattern"));            //設置ComponentScan對象的includeFilters包含的屬性          for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {              for (TypeFilter typeFilter : typeFiltersFor(filter)) {                  scanner.addIncludeFilter(typeFilter);              }          }          //設置ComponentScan對象的excludeFilters不包含的屬性          for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {              for (TypeFilter typeFilter : typeFiltersFor(filter)) {                  scanner.addExcludeFilter(typeFilter);              }          }            //是否懶載入          boolean lazyInit = componentScan.getBoolean("lazyInit");          if (lazyInit) {              scanner.getBeanDefinitionDefaults().setLazyInit(true);          }            //包路徑          Set<String> basePackages = new LinkedHashSet<>();          String[] basePackagesArray = componentScan.getStringArray("basePackages");          for (String pkg : basePackagesArray) {              String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),                      ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);              Collections.addAll(basePackages, tokenized);          }          for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {              basePackages.add(ClassUtils.getPackageName(clazz));          }          if (basePackages.isEmpty()) {              basePackages.add(ClassUtils.getPackageName(declaringClass));          }            scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {              @Override              protected boolean matchClassName(String className) {                  return declaringClass.equals(className);              }          });          //真正的進行掃描解析          return scanner.doScan(StringUtils.toStringArray(basePackages));      }

  進入真正的進行掃描解析scanner.doScan(StringUtils.toStringArray(basePackages))方法:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {          Assert.notEmpty(basePackages, "At least one base package must be specified");          //創建bean定義的holder對象用於保存掃描後生成的bean定義對象          Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();          //循環我們的包路徑集合          for (String basePackage : basePackages) {              //找到候選的@Component              Set<BeanDefinition> candidates = findCandidateComponents(basePackage);              for (BeanDefinition candidate : candidates) {                    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);                  candidate.setScope(scopeMetadata.getScopeName());                  //設置我們的beanName                  String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);                  //處理@AutoWired相關的                  if (candidate instanceof AbstractBeanDefinition) {                      postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);                  }                  //處理jsr250相關的組件                  if (candidate instanceof AnnotatedBeanDefinition) {                      AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);                  }                  //把我們解析出來的組件bean定義註冊到Spring IoC容器中                  if (checkCandidate(beanName, candidate)) {                      BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);                      definitionHolder =                              AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);                      beanDefinitions.add(definitionHolder);                      //註冊到Spring IoC容器中                      registerBeanDefinition(definitionHolder, this.registry);                  }              }          }          return beanDefinitions;      }

  Debug解析:

  進過org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan處理,Spring IoC容器中Bean的定義有12個了;

  ② 接下來處理@Import註解導入的Bean組件:

  進入處理@Import註解的processImports(configClass, sourceClass, getImports(sourceClass), true)方法:

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,              Collection<SourceClass> importCandidates, boolean checkForCircularImports) {            if (importCandidates.isEmpty()) {              return;          }            if (checkForCircularImports && isChainedImportOnStack(configClass)) {              this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));          }          else {              this.importStack.push(configClass);              try {                  //獲取我們Import導入進來的所有組件                  for (SourceClass candidate : importCandidates) {                      //判斷該組件是不是實現了ImportSelector的                      if (candidate.isAssignable(ImportSelector.class)) {                          // Candidate class is an ImportSelector -> delegate to it to determine imports                          Class<?> candidateClass = candidate.loadClass();                          //實例化我們的SelectImport組件                          ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);                          //調用相關的aware方法                          ParserStrategyUtils.invokeAwareMethods(                                  selector, this.environment, this.resourceLoader, this.registry);                          //判斷是不是延時的DeferredImportSelectors,是這個類型不進行處理                          if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {                              this.deferredImportSelectors.add(                                      new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));                          }                          else {//不是延時的調用selector的selectImports                              String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());                              //反之SelectImport導入進來的又是Import進來的 所以遞歸解析                              Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);                              processImports(configClass, currentSourceClass, importSourceClasses, false);                          }                      }                      //判斷我們導入的組件是不是ImportBeanDefinitionRegistrar                      else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {                          // Candidate class is an ImportBeanDefinitionRegistrar ->                          // delegate to it to register additional bean definitions                          Class<?> candidateClass = candidate.loadClass();                          //實例話我們的ImportBeanDefinitionRegistrar對象                          ImportBeanDefinitionRegistrar registrar =                                  BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);                          ParserStrategyUtils.invokeAwareMethods(                                  registrar, this.environment, this.resourceLoader, this.registry);                          //保存我們的ImportBeanDefinitionRegistrar對象                          configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());                      }                      else {//就是一個普通的組件  但是防止我們普通的組件是一個配置類 所以還是直接走了processConfigurationClass()方法                          this.importStack.registerImport(                                  currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());                          processConfigurationClass(candidate.asConfigClass(configClass));                      }                  }              }              catch (BeanDefinitionStoreException ex) {                  throw ex;              }              catch (Throwable ex) {                  throw new BeanDefinitionStoreException(                          "Failed to process import candidates for configuration class [" +                          configClass.getMetadata().getClassName() + "]", ex);              }              finally {                  this.importStack.pop();              }          }      }

   ③ 接下來處理@ImportSource比如@ImportResource(“classpath:circulation-di.xml”),基於xml的(

   ④ 接下來處理@Bean:

  至此解析完成,注意@Import、@ImportSource、@Bean的定義還未註冊到Spring IoC的容器中去

  接下來將剩餘的Bean定義資訊註冊到Spring IoC容器中:

   進入真正的把我們解析出來的配置類註冊到容器中this.reader.loadBeanDefinitions(configClasses)方法:

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {          TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();          //註冊我們的配置類到容器中          for (ConfigurationClass configClass : configurationModel) {              loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);          }      }

  進入loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator)方法:

private void loadBeanDefinitionsForConfigurationClass(              ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {            if (trackedConditionEvaluator.shouldSkip(configClass)) {              String beanName = configClass.getBeanName();              if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {                  this.registry.removeBeanDefinition(beanName);              }              this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());              return;          }            //是不是通過@Import導入進來的          if (configClass.isImported()) {              registerBeanDefinitionForImportedConfigurationClass(configClass);          }          //是不是通過我們的@Bean導入進來的組件          for (BeanMethod beanMethod : configClass.getBeanMethods()) {              loadBeanDefinitionsForBeanMethod(beanMethod);          }            //是不是通過@ImportResources導入進來的          loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());          //是不是通過ImportBeanDefinition註解導入進來的          loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());      }

  ① 通過@Import導入進來的執行registerBeanDefinitionForImportedConfigurationClass(configClass)方法:

private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {          //獲取我們的配置類的源資訊          AnnotationMetadata metadata = configClass.getMetadata();          //構建為我們的bean定義          AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);          //設置他的scope          ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);          configBeanDef.setScope(scopeMetadata.getScopeName());          //獲取bean的名稱          String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);          //處理我們的JRS250組件的          AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);          definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);          //註冊我們的bean定義到我們的容器中          this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());          configClass.setBeanName(configBeanName);            if (logger.isDebugEnabled()) {              logger.debug("Registered bean definition for imported class '" + configBeanName + "'");          }      }

   ② 通過@Bean導入進來的執行loadBeanDefinitionsForBeanMethod(beanMethod)方法:

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {          ConfigurationClass configClass = beanMethod.getConfigurationClass();          MethodMetadata metadata = beanMethod.getMetadata();          String methodName = metadata.getMethodName();            // Do we need to mark the bean as skipped by its condition?          if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {              configClass.skippedBeanMethods.add(methodName);              return;          }          if (configClass.skippedBeanMethods.contains(methodName)) {              return;          }            AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);          Assert.state(bean != null, "No @Bean annotation attributes");            // Consider name and any aliases          List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));          String beanName = (!names.isEmpty() ? names.remove(0) : methodName);            // Register aliases even when overridden          for (String alias : names) {              this.registry.registerAlias(beanName, alias);          }            // Has this effectively been overridden before (e.g. via XML)?          if (isOverriddenByExistingDefinition(beanMethod, beanName)) {              if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {                  throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),                          beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +                          "' clashes with bean name for containing configuration class; please make those names unique!");              }              return;          }            ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);          beanDef.setResource(configClass.getResource());          beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));            if (metadata.isStatic()) {              // static @Bean method              beanDef.setBeanClassName(configClass.getMetadata().getClassName());              beanDef.setFactoryMethodName(methodName);          }          else {              // instance @Bean method              beanDef.setFactoryBeanName(configClass.getBeanName());              beanDef.setUniqueFactoryMethodName(methodName);          }          beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);          beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);            AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);            Autowire autowire = bean.getEnum("autowire");          if (autowire.isAutowire()) {              beanDef.setAutowireMode(autowire.value());          }            String initMethodName = bean.getString("initMethod");          if (StringUtils.hasText(initMethodName)) {              beanDef.setInitMethodName(initMethodName);          }            String destroyMethodName = bean.getString("destroyMethod");          beanDef.setDestroyMethodName(destroyMethodName);            // Consider scoping          ScopedProxyMode proxyMode = ScopedProxyMode.NO;          AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);          if (attributes != null) {              beanDef.setScope(attributes.getString("value"));              proxyMode = attributes.getEnum("proxyMode");              if (proxyMode == ScopedProxyMode.DEFAULT) {                  proxyMode = ScopedProxyMode.NO;              }          }            // Replace the original bean definition with the target one, if necessary          BeanDefinition beanDefToRegister = beanDef;          if (proxyMode != ScopedProxyMode.NO) {              BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(                      new BeanDefinitionHolder(beanDef, beanName), this.registry,                      proxyMode == ScopedProxyMode.TARGET_CLASS);              beanDefToRegister = new ConfigurationClassBeanDefinition(                      (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);          }            if (logger.isDebugEnabled()) {              logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",                      configClass.getMetadata().getClassName(), beanName));          }          this.registry.registerBeanDefinition(beanName, beanDefToRegister);      }

  ③ 通過@ImportResources導入進來的執行loadBeanDefinitionsFromImportedResources(configClass.getImportedResources())方法:

private void loadBeanDefinitionsFromImportedResources(              Map<String, Class<? extends BeanDefinitionReader>> importedResources) {            Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>();            importedResources.forEach((resource, readerClass) -> {              // Default reader selection necessary?              if (BeanDefinitionReader.class == readerClass) {                  if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {                      // When clearly asking for Groovy, that's what they'll get...                      readerClass = GroovyBeanDefinitionReader.class;                  }                  else {                      // Primarily ".xml" files but for any other extension as well                      readerClass = XmlBeanDefinitionReader.class;                  }              }                BeanDefinitionReader reader = readerInstanceCache.get(readerClass);              if (reader == null) {                  try {                      // Instantiate the specified BeanDefinitionReader                      reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);                      // Delegate the current ResourceLoader to it if possible                      if (reader instanceof AbstractBeanDefinitionReader) {                          AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);                          abdr.setResourceLoader(this.resourceLoader);                          abdr.setEnvironment(this.environment);                      }                      readerInstanceCache.put(readerClass, reader);                  }                  catch (Throwable ex) {                      throw new IllegalStateException(                              "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");                  }              }                // TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations              reader.loadBeanDefinitions(resource);          });      }

  ④ 通過ImportBeanDefinition註解導入進來的執行loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars())方法:

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {          registrars.forEach((registrar, metadata) ->                  registrar.registerBeanDefinitions(metadata, this.registry));      }

   至此第一步裡面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法執行完畢!!!!

  下一步:又去容器中獲取BeanDefinitionRegistryPostProcessor的bean的處理器名稱 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false) 此時就有了自己定義的BeanDefinitionRegistryPostProcessor了,接下來調用自定義的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry後置方法,然後再調用postProcessBeanFactory原因是BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor;

  最後一步:獲取容器中所有的BeanFactoryPostProcessor的名稱 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false) 此時就有了自己定義的BeanFactoryPostProcessor了,接下來調用自定義的BeanFactoryPostProcessor的postProcessBeanFactory方法;

  完整的Spring IoC源碼解析見:Spring系列(三):Spring IoC源碼解析

三、Spring IoC掃描Bean的流程圖

  總結:通過調用我們的Bean工廠的後置處理器,第一步:ConfigurationClassPostProcessor,解析我們的配置類,將所有的Bean的定義資訊註冊到Spring IoC容器中;第二步調用自定義的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinition Registry後置方法,然後再調用postProcessBeanFactory;最後調用自定義的BeanFactoryPostProcessor的postProcessBean Factory方法