spring源碼分析1

接著上一篇文章將 refresh方法
首先看一下測試項(xiàng)目代碼
主類,將Myconfiguration.class注入進(jìn)ApplictionContext


image.png

配置類


image.png

Car類實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口
image.png

MySpringBean標(biāo)注了@Component
image.png

看一下refresh方法,(AbstractApplicationContext#refresh)

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

這里就是spring里關(guān)于bean的核心方法,筆者并沒有全部看過,這里也介紹bean的主線代碼,繼續(xù)分析
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法,
這里就涉及到最重要的類ConfigurationClassPostProcess,首先看一下繼承關(guān)系,實(shí)現(xiàn)了
BeanDefinitionRegistryPostProcessor(postProcessBeanDefinitionRegistry)和
BeanFactoryPostProcessor(postProcessBeanFactory),后續(xù)對調(diào)用這兩個(gè)方法


image.png

image.png

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中
主要作用就是通過實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor 接口類(一般指的是ConfigurationClassPostProcessor類)的postProcessBeanDefinitionRegistry方法掃面項(xiàng)目,將需要的類(比如@service @controller @configuration注解標(biāo)注的類)加入到beanDefinitionMap中,并調(diào)用實(shí)現(xiàn)BeanFactoryPostProcessor的類的
postProcessBeanFactory方法修改beanDefinition,
在invokeBeanFactoryPostProcessors有g(shù)etBean方法,會將bean放到一級緩存中,但是沒有賦值屬性


image.png
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
//已經(jīng)處理過的bean,防止bean后置處理器被重復(fù)的執(zhí)行
   Set<String> processedBeans = new HashSet<>();
//判斷beanFacroty是否實(shí)現(xiàn)BeanDefinitionRegistry,因?yàn)樾枰@取bean和注冊bean的功能
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// BeanFactoryPostProcessor實(shí)現(xiàn)類的集合,過濾的是入?yún)eanFactoryPostProcessors中的
// BeanFactoryPostProcessor接口的實(shí)現(xiàn)類
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BeanDefinitionRegistryPostProcessor實(shí)現(xiàn)類的集合
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// beanFactoryPostProcessors通過AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的,
//springboot在啟動的時(shí)候會調(diào)用addBeanFactoryPostProcessor方法
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//如果手動添加的BeanDefinitionRegistry是BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn)類
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
//調(diào)用postProcessBeanDefinitionRegistry方法
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到registryProcessors中
            registryProcessors.add(registryProcessor);
         }
         else {
//如果不是BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn)類,就是BeanFactoryPostProcessor的實(shí)現(xiàn)類,添加到regularPostProcessors
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//從DefaultListableBeanFactory的beanDefinitionNames成員變量中獲取//BeanDefinitionRegistryPostProcessor的bean的處理器名稱
      String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
//過濾,只留實(shí)現(xiàn)PriorityOrdered接口的類,排序用
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean獲取bean,添加到currentRegistryProcessors中,這是馬上就要處理的集合,
// getBean獲取的類是ConfigurationClassPostProcessor
//getBean的源碼后續(xù)會分析到
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//添加到processedBeans中,這是代表已經(jīng)處理的集合
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加registryProcessors集合
      registryProcessors.addAll(currentRegistryProcessors);
//執(zhí)行postProcessBeanDefinitionRegistry方法,這里出現(xiàn)的一般都是
//ConfigurationClassPostProcessor ,這個(gè)類是springioc容器最重要的類
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//清空currentRegistryProcessors,后續(xù)還會用到
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//從DefaultListableBeanFactory的beanDefinitionNames成員變量中獲取
//BeanDefinitionRegistryPostProcessor的bean的處理器名稱,代碼和上面一樣,執(zhí)行實(shí)現(xiàn)
//Ordered接口的類,排序用
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {

//唯一不同的是,這里多了一個(gè)判斷條件,過濾掉已經(jīng)指定過的bean
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//執(zhí)行剩下的bean,因?yàn)轫?xiàng)目中創(chuàng)建了Car類并且實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor
//接口,所以這里剩下的只有car
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
// currentRegistryProcessors馬上就要處理的集合
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//已經(jīng)處理的bean,避免重復(fù)執(zhí)行
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//調(diào)用registryProcessors和regularPostProcessors的postProcessBeanFactory方法

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

   else {
      // Invoke factory processors registered with the context instance.
//如果bean工廠沒有實(shí)現(xiàn)BeanDefinitionRegistry    接口,說明沒有注冊Bean定義的能力
// 那么就直接調(diào)用BeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
//獲取BeanFactoryPostProcessor接口的實(shí)例名稱
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
//實(shí)現(xiàn)PriorityOrdered和BeanFactoryPostProcessors接口的類
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//實(shí)現(xiàn)Ordered和BeanFactoryPostProcessors接口類名稱(beanDefinitionMap的key)
   List<String> orderedPostProcessorNames = new ArrayList<>();
//沒有實(shí)現(xiàn)PriorityOrdered和Ordered接口的類名稱(beanDefinitionMap的key)
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
//已經(jīng)處理過的bean,什么也不做
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
//實(shí)現(xiàn)PriorityOrdered接口的類getBean并add進(jìn)priorityOrderedPostProcessors
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
//實(shí)現(xiàn)Ordered接口類名稱add orderedPostProcessorNames
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
//剩余類名稱的add進(jìn)nonOrderedPostProcessorNames
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
//下面的代碼就是執(zhí)行BeanFactoryPostProcessor的postProcessBeanFactory方法
   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   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();
}

下面兩張圖體現(xiàn)了當(dāng)調(diào)用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法之后將car注入到beanDefinitionMap中


image.png

image.png

invokeBeanDefinitionRegistryPostProcessors方法調(diào)用類的
postProcessBeanDefinitionRegistry方法,其實(shí)就是調(diào)用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法,為什么是這個(gè)類,已經(jīng)分析過了,當(dāng)調(diào)用postProcessBeanDefinitionRegistry方法的時(shí)候,最終調(diào)用的是processConfigBeanDefinitions方法,上兩張圖注意到car的注入,那car是如何通過processConfigBeanDefinitions方法,注入進(jìn)ioc容器中的


public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//從現(xiàn)有的beanDefinitionNames中獲取bean的名稱①
   String[] candidateNames = registry.getBeanDefinitionNames();

   for (String beanName : candidateNames) {
//獲取beanDefinition
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判斷類是否被解析過,解析過的類返回不為null,這里涉及到類是完成配置類還是非完全配置類
      if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
         if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
         }
      }
//判斷類是否有@Configuration注解,如果沒有看是否標(biāo)注了@Component@ComponentScan
//@Import@ImportResource,如果還沒有則看是否包含@Bean注解的方法,以上都沒有則返回false ② 
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//執(zhí)行完下面的方法時(shí)configCandidates只有MyConfiguration配置類,
//有MyConfiguration,不是因?yàn)闃?biāo)注了@configuration注解是在new AnnotationConfigApplicationContext(Myconfiguration.class)時(shí)候,存入進(jìn)beanDefinitionMaps中的
//這里有個(gè)疑問為什么
//沒有MySpringBean呢,到現(xiàn)在為止還沒有涉及到注解,在解析MyConfiguration配置類的代碼的時(shí)候
//通過MyConfiguration類的@ComponentScan注解就會
//把MySpringBean掃描出來并放到beanDefinitionMap中, 
//MyConfiguration標(biāo)注了@Configuration,不但滿足了上面的
//checkConfigurationClassCandidate條件,而且還是FULL類型的配置類
         configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
   }

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

   // Sort by previously determined @Order value, if applicable
//根據(jù)類的@Order排序,這就是我們經(jīng)常使用的,用@Order來決定類解析的順序,
//@order小的排在前面
   configCandidates.sort((bd1, bd2) -> {
      int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
      int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
      return Integer.compare(i1, i2);
   });

   // Detect any custom bean name generation strategy supplied through the enclosing application context
   SingletonBeanRegistry sbr = null;
   if (registry instanceof SingletonBeanRegistry) {
      sbr = (SingletonBeanRegistry) registry;
      if (!this.localBeanNameGeneratorSet) {
         BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
               AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
         if (generator != null) {
            this.componentScanBeanNameGenerator = generator;
            this.importBeanNameGenerator = generator;
         }
      }
   }

   if (this.environment == null) {
      this.environment = new StandardEnvironment();
   }

   // Parse each @Configuration class
//創(chuàng)建解析器
   ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
         this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//此時(shí)configCandidates只有MyConfiguration一個(gè)類
   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
   Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
   do {
      StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析配置類,當(dāng)執(zhí)行這個(gè)方法的時(shí)候,就會解析出很多類,其中就包括MySpringBean類③
      parser.parse(candidates);
      parser.validate();
//獲取掃描到的類,此時(shí)還沒有放到beanDefinitionMap中
      Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
//去除已經(jīng)解析過的類
      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());
      }
//將解析出來的配置類存放到beanDefinitionMap中,④
      this.reader.loadBeanDefinitions(configClasses);
//將加載的類放到alreadyParsed中
      alreadyParsed.addAll(configClasses);
      processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

      candidates.clear();
//因?yàn)橛袙呙璧念惔娣诺絙eanDefinitionMap中,并且類中可能還有@Bean @Import等注解,所以下面一定大于
      if (registry.getBeanDefinitionCount() > candidateNames.length) {
         String[] newCandidateNames = registry.getBeanDefinitionNames();
// candidateNames 為方法最開始定義的,里面只有spring啟動的時(shí)候存放的配置類         
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();
   }
}

①解釋為什么configCandidates只有MyConfiguration配置類


image.png

②ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
我們只關(guān)注checkConfigurationClassCandidate方法中的部分代碼

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
//判斷是否標(biāo)注了@Configuration并且proxyBeanMethods屬性是否為false再取反即使判斷是否為true,默認(rèn)為true
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
//定義該類為完全配置類,對于什么是完全配置類后續(xù)會分析
   beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//判斷否標(biāo)注了@Component@ComponentScan@Import@ImportResource,如果還沒有則看是否包含@Bean注解的方法, 
else if (config != null || isConfigurationCandidate(metadata)) {
   beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
//以上都沒有則返回false
else {
   return false;
}

③ 解析到的配置類

image.png

Parse方法調(diào)用結(jié)束后,共掃描出3個(gè)類
image.png

查看parser.parse(candidates)
ConfigurationClassParser#parse(Set<BeanDefinitionHolder> configCandidates)
-->ConfigurationClassParser#processConfigurationClass
-->ConfigurationClassParser#doProcessConfigurationClass
在doProcessConfigurationClass方法中可以大概的看出
主要是看類是否包含@Component @PropertySources @ComponentScans @ImportResource注釋 如果ComponentScans注解,通過路徑還要掃描類,
提一下在spring解析的時(shí)候,如果@ComponentScans的basePackages為空的時(shí)候,掃描路徑就是當(dāng)前類所在的包,這段代碼在ComponentScanAnnotationParser的parse方法中

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));
}
//如果為null,使用當(dāng)前類所在的包
if (basePackages.isEmpty()) {
   basePackages.add(ClassUtils.getPackageName(declaringClass));
}

下一步呢 就是把包下所有的類都找到,并根據(jù)excludeFilters includeFilters的規(guī)則,找到標(biāo)注了@Component注解的類,這里就不分析了,關(guān)注一下
ClassPathBeanDefinitionScanner#doScan方法下的
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
basePackage就是包的掃描路徑, findCandidateComponents方法中查找包下的所有類,在遍歷,過濾出標(biāo)注了@Component注解的類

image.png

this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); 方法的第一行代碼就new ClassPathBeanDefinitionScanner,并沒有使用AnnotationConfigApplicationContext構(gòu)造方法new ClassPathBeanDefinitionScanner對象,方法里面解析了@ConfigurationScan注解的屬性,根據(jù)屬性掃描類,最后scanner.doScan(StringUtils.toStringArray(basePackages));來掃描,并判斷beanName 不能重復(fù),如果重復(fù)則拋出異常
還要介紹一下
ConfigurationClassParser# doProcessConfigurationClass的下面這段代碼
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
主要是通過@Import(ImportSelector實(shí)現(xiàn)類.class) 的selectImports導(dǎo)入的類
包裝成configClass,并賦值importBy為標(biāo)注了@import的元類
http://www.itdecent.cn/p/4223ea69eb1f 這篇文章分析過是符合導(dǎo)入的
到此為止,把所有@ConfigurationScan掃描的類和@import的類都放到configClasses中
是通過ConfigurationClassParser#processConfigurationClass
this.configurationClasses.put(configClass, configClass);
這個(gè)方法存放進(jìn)configClasses的
image.png

  • ④this.reader.loadBeanDefinitions(configClasses); 將掃描的類加載進(jìn)beanDefinitionMap中,并在加載之前,掃面類中是否含有@Bean注解,如果有也將掃面進(jìn)beanDefinitionMap中
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;
   }
//如果當(dāng)前的類是通過@Import導(dǎo)入的,是在
// ConfigurationClassParser#doProcessConfigurationClass的
//processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
//將標(biāo)注@Import獲取出來的,這段代碼就是將@Import標(biāo)注的類存放beanDefinitionMap中
   if (configClass.isImported()) {
      registerBeanDefinitionForImportedConfigurationClass(configClass);
   }
//如果configClass中有@bean方法,也將返回類存放進(jìn)beanDefinitionMap中,key為方法名稱
   for (BeanMethod beanMethod : configClass.getBeanMethods()) {
      loadBeanDefinitionsForBeanMethod(beanMethod);
   }
//是不是通過@ImportResources注解導(dǎo)入進(jìn)來的
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//是否實(shí)現(xiàn)ImportBeanDefinitionRegistrar,  ImportBeanDefinitionRegistrar是擴(kuò)展接口//通過registerBeanDefinitions手動的注冊beanDefinition, 實(shí)現(xiàn)//ImportBeanDefinitionRegistrar的類都是通過@Import導(dǎo)入的,并且實(shí)現(xiàn)類本身不會注入進(jìn)//beanDefinitionMap中
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

以上是關(guān)于ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法
下面介紹ConfigruationClassPostProcessor#postProcessBeanFactory方法
那我們在回到最開始說的
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);調(diào)用的就
ConfigruationClassPostProcessor#postProcessBeanFactory方法

@Override
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));
}

enhanceConfigurationClasses方法對Bean的增強(qiáng)
遍歷所有的beanDefinitionMap中的beanDefinition
如果類ConfigurationClassUtils.CONFIGURATION_CLASS_FULL前面提到過,就是類被@Configuration注釋了,就會被CGLIB代理,將beanDefinition中的beanClass屬性替換成被代理之后的類,
代理類的用處是什么呢,下面兩張圖可以解釋,本次分析的
AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);代碼不會創(chuàng)建Bean,下面兩張圖不是執(zhí)行invokeBeanFactoryPostProcessors代碼時(shí)打印的


image.png

image.png

還沒有介紹@Conditional的注解的使用,
this.reader.loadBeanDefinitions(configClasses)執(zhí)行這個(gè)方法的時(shí)候,會解析@Conditional的一系列注解,springboot 中使用的是SpringBootCondition#matches方法,
ConditionOutcome outcome = getMatchOutcome(context, metadata);
getMatchOutcome方法是抽象方法具體的實(shí)現(xiàn),如下就是OnBeanCondition的getMatchOutcome方法

@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean

總結(jié)一下
本文其實(shí)主要介紹的就是

AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);方法
invokeBeanFactoryPostProcessors方法主要就是調(diào)用ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法
postProcessBeanDefinitionRegistry方法的作用是首先通過@ComponentScans掃描標(biāo)注了@Component的類添加到beanDefinitionMap,遍歷beanDefinitionMap如果標(biāo)注@Import注解,根據(jù)selectImports返回的數(shù)組添加到configClasses中,再遍歷configClasses,把標(biāo)注@Bean @ImportSource 包裝成beanDefintion添加到beanDefinitionMap中.
postProcessBeanFactory方法標(biāo)注了@Configuration類,定義為增強(qiáng)類CGLIB代理,將beanDefinition中的beanClass屬性替換成被代理之后的類.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容