springspring

spring源码分析1

2021-08-17  本文已影响0人  念䋛

接着上一篇文章将 refresh方法
首先看一下测试项目代码
主类,将Myconfiguration.class注入进ApplictionContext


image.png

配置类


image.png
Car类实现了BeanDefinitionRegistryPostProcessor接口
image.png
MySpringBean标注了@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因为继承   GenericApplicationContext
//点进obtainFreshBeanFactory()方法,发现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里关于bean的核心方法,笔者并没有全部看过,这里也介绍bean的主线代码,继续分析
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法,
这里就涉及到最重要的类ConfigurationClassPostProcess,首先看一下继承关系,实现了
BeanDefinitionRegistryPostProcessor(postProcessBeanDefinitionRegistry)和
BeanFactoryPostProcessor(postProcessBeanFactory),后续对调用这两个方法


image.png
image.png

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中
主要作用就是通过实现BeanDefinitionRegistryPostProcessor 接口类(一般指的是ConfigurationClassPostProcessor类)的postProcessBeanDefinitionRegistry方法扫面项目,将需要的类(比如@service @controller @configuration注解标注的类)加入到beanDefinitionMap中,并调用实现BeanFactoryPostProcessor的类的
postProcessBeanFactory方法修改beanDefinition,
在invokeBeanFactoryPostProcessors有getBean方法,会将bean放到一级缓存中,但是没有赋值属性


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

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
//已经处理过的bean,防止bean后置处理器被重复的执行
   Set<String> processedBeans = new HashSet<>();
//判断beanFacroty是否实现BeanDefinitionRegistry,因为需要获取bean和注册bean的功能
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// BeanFactoryPostProcessor实现类的集合,过滤的是入参beanFactoryPostProcessors中的
// BeanFactoryPostProcessor接口的实现类
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BeanDefinitionRegistryPostProcessor实现类的集合
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// beanFactoryPostProcessors通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的,
//springboot在启动的时候会调用addBeanFactoryPostProcessor方法
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//如果手动添加的BeanDefinitionRegistry是BeanDefinitionRegistryPostProcessor的实现类
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
//调用postProcessBeanDefinitionRegistry方法
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到registryProcessors中
            registryProcessors.add(registryProcessor);
         }
         else {
//如果不是BeanDefinitionRegistryPostProcessor的实现类,就是BeanFactoryPostProcessor的实现类,添加到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) {
//过滤,只留实现PriorityOrdered接口的类,排序用
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean获取bean,添加到currentRegistryProcessors中,这是马上就要处理的集合,
// getBean获取的类是ConfigurationClassPostProcessor
//getBean的源码后续会分析到
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//添加到processedBeans中,这是代表已经处理的集合
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加registryProcessors集合
      registryProcessors.addAll(currentRegistryProcessors);
//执行postProcessBeanDefinitionRegistry方法,这里出现的一般都是
//ConfigurationClassPostProcessor ,这个类是springioc容器最重要的类
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//清空currentRegistryProcessors,后续还会用到
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//从DefaultListableBeanFactory的beanDefinitionNames成员变量中获取
//BeanDefinitionRegistryPostProcessor的bean的处理器名称,代码和上面一样,执行实现
//Ordered接口的类,排序用
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {

//唯一不同的是,这里多了一个判断条件,过滤掉已经指定过的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.
//执行剩下的bean,因为项目中创建了Car类并且实现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));
//已经处理的bean,避免重复执行
               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.
//调用registryProcessors和regularPostProcessors的postProcessBeanFactory方法

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

   else {
      // Invoke factory processors registered with the context instance.
//如果bean工厂没有实现BeanDefinitionRegistry    接口,说明没有注册Bean定义的能力
// 那么就直接调用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接口的实例名称
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
//实现PriorityOrdered和BeanFactoryPostProcessors接口的类
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//实现Ordered和BeanFactoryPostProcessors接口类名称(beanDefinitionMap的key)
   List<String> orderedPostProcessorNames = new ArrayList<>();
//没有实现PriorityOrdered和Ordered接口的类名称(beanDefinitionMap的key)
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
//已经处理过的bean,什么也不做
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
//实现PriorityOrdered接口的类getBean并add进priorityOrderedPostProcessors
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
//实现Ordered接口类名称add orderedPostProcessorNames
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
//剩余类名称的add进nonOrderedPostProcessorNames
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
//下面的代码就是执行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();
}

下面两张图体现了当调用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法之后将car注入到beanDefinitionMap中


image.png
image.png

invokeBeanDefinitionRegistryPostProcessors方法调用类的
postProcessBeanDefinitionRegistry方法,其实就是调用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法,为什么是这个类,已经分析过了,当调用postProcessBeanDefinitionRegistry方法的时候,最终调用的是processConfigBeanDefinitions方法,上两张图注意到car的注入,那car是如何通过processConfigBeanDefinitions方法,注入进ioc容器中的


public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//从现有的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注解,如果没有看是否标注了@Component@ComponentScan
//@Import@ImportResource,如果还没有则看是否包含@Bean注解的方法,以上都没有则返回false ② 
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//执行完下面的方法时configCandidates只有MyConfiguration配置类,
//有MyConfiguration,不是因为标注了@configuration注解是在new AnnotationConfigApplicationContext(Myconfiguration.class)时候,存入进beanDefinitionMaps中的
//这里有个疑问为什么
//没有MySpringBean呢,到现在为止还没有涉及到注解,在解析MyConfiguration配置类的代码的时候
//通过MyConfiguration类的@ComponentScan注解就会
//把MySpringBean扫描出来并放到beanDefinitionMap中, 
//MyConfiguration标注了@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
//根据类的@Order排序,这就是我们经常使用的,用@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
//创建解析器
   ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
         this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//此时configCandidates只有MyConfiguration一个类
   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
   Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
   do {
      StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析配置类,当执行这个方法的时候,就会解析出很多类,其中就包括MySpringBean类③
      parser.parse(candidates);
      parser.validate();
//获取扫描到的类,此时还没有放到beanDefinitionMap中
      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());
      }
//将解析出来的配置类存放到beanDefinitionMap中,④
      this.reader.loadBeanDefinitions(configClasses);
//将加载的类放到alreadyParsed中
      alreadyParsed.addAll(configClasses);
      processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

      candidates.clear();
//因为有扫描的类存放到beanDefinitionMap中,并且类中可能还有@Bean @Import等注解,所以下面一定大于
      if (registry.getBeanDefinitionCount() > candidateNames.length) {
         String[] newCandidateNames = registry.getBeanDefinitionNames();
// candidateNames 为方法最开始定义的,里面只有spring启动的时候存放的配置类         
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)
我们只关注checkConfigurationClassCandidate方法中的部分代码

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
//判断是否标注了@Configuration并且proxyBeanMethods属性是否为false再取反即使判断是否为true,默认为true
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
//定义该类为完全配置类,对于什么是完全配置类后续会分析
   beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//判断否标注了@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方法调用结束后,共扫描出3个类
image.png
查看parser.parse(candidates)
ConfigurationClassParser#parse(Set<BeanDefinitionHolder> configCandidates)
-->ConfigurationClassParser#processConfigurationClass
-->ConfigurationClassParser#doProcessConfigurationClass
在doProcessConfigurationClass方法中可以大概的看出
主要是看类是否包含@Component @PropertySources @ComponentScans @ImportResource注释 如果ComponentScans注解,通过路径还要扫描类,
提一下在spring解析的时候,如果@ComponentScans的basePackages为空的时候,扫描路径就是当前类所在的包,这段代码在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,使用当前类所在的包
if (basePackages.isEmpty()) {
   basePackages.add(ClassUtils.getPackageName(declaringClass));
}

下一步呢 就是把包下所有的类都找到,并根据excludeFilters includeFilters的规则,找到标注了@Component注解的类,这里就不分析了,关注一下
ClassPathBeanDefinitionScanner#doScan方法下的
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
basePackage就是包的扫描路径, findCandidateComponents方法中查找包下的所有类,在遍历,过滤出标注了@Component注解的类

image.png
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); 方法的第一行代码就new ClassPathBeanDefinitionScanner,并没有使用AnnotationConfigApplicationContext构造方法new ClassPathBeanDefinitionScanner对象,方法里面解析了@ConfigurationScan注解的属性,根据属性扫描类,最后scanner.doScan(StringUtils.toStringArray(basePackages));来扫描,并判断beanName 不能重复,如果重复则抛出异常
还要介绍一下
ConfigurationClassParser# doProcessConfigurationClass的下面这段代码
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
主要是通过@Import(ImportSelector实现类.class) 的selectImports导入的类
包装成configClass,并赋值importBy为标注了@import的元类
https://www.jianshu.com/p/4223ea69eb1f 这篇文章分析过是符合导入的
到此为止,把所有@ConfigurationScan扫描的类和@import的类都放到configClasses中
是通过ConfigurationClassParser#processConfigurationClass
this.configurationClasses.put(configClass, configClass);
这个方法存放进configClasses的
image.png
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导入的,是在
// ConfigurationClassParser#doProcessConfigurationClass的
//processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
//将标注@Import获取出来的,这段代码就是将@Import标注的类存放beanDefinitionMap中
   if (configClass.isImported()) {
      registerBeanDefinitionForImportedConfigurationClass(configClass);
   }
//如果configClass中有@bean方法,也将返回类存放进beanDefinitionMap中,key为方法名称
   for (BeanMethod beanMethod : configClass.getBeanMethods()) {
      loadBeanDefinitionsForBeanMethod(beanMethod);
   }
//是不是通过@ImportResources注解导入进来的
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//是否实现ImportBeanDefinitionRegistrar,  ImportBeanDefinitionRegistrar是扩展接口//通过registerBeanDefinitions手动的注册beanDefinition, 实现//ImportBeanDefinitionRegistrar的类都是通过@Import导入的,并且实现类本身不会注入进//beanDefinitionMap中
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

以上是关于ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法
下面介绍ConfigruationClassPostProcessor#postProcessBeanFactory方法
那我们在回到最开始说的
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);调用的就
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的增强
遍历所有的beanDefinitionMap中的beanDefinition
如果类ConfigurationClassUtils.CONFIGURATION_CLASS_FULL前面提到过,就是类被@Configuration注释了,就会被CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类,
代理类的用处是什么呢,下面两张图可以解释,本次分析的
AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);代码不会创建Bean,下面两张图不是执行invokeBeanFactoryPostProcessors代码时打印的


image.png
image.png

还没有介绍@Conditional的注解的使用,
this.reader.loadBeanDefinitions(configClasses)执行这个方法的时候,会解析@Conditional的一系列注解,springboot 中使用的是SpringBootCondition#matches方法,
ConditionOutcome outcome = getMatchOutcome(context, metadata);
getMatchOutcome方法是抽象方法具体的实现,如下就是OnBeanCondition的getMatchOutcome方法

@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean

总结一下
本文其实主要介绍的就是

AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);方法
invokeBeanFactoryPostProcessors方法主要就是调用ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法
postProcessBeanDefinitionRegistry方法的作用是首先通过@ComponentScans扫描标注了@Component的类添加到beanDefinitionMap,遍历beanDefinitionMap如果标注@Import注解,根据selectImports返回的数组添加到configClasses中,再遍历configClasses,把标注@Bean @ImportSource 包装成beanDefintion添加到beanDefinitionMap中.
postProcessBeanFactory方法标注了@Configuration类,定义为增强类CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类.

上一篇下一篇

猜你喜欢

热点阅读