乐趣区

关于java:Spring的BeanDefinition的收集过程

调试代码
以注解形式阐明 BeanDefinition 的收集过程, 调试代码如下:

public class AnnotationACTest {public static void main(String[] args) {
      // new 一个利用上下文的时候, 会注册一些外部的 BeanFactoryPostProcessor 的 beanDefinition
 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
 ac.register(BeanConfig.class);
 ac.refresh();}
}

BeanConfig

@Configuration
@ComponentScan("com.mfy.test.bean")
@EnableAspectJAutoProxy
public class BeanConfig {
   @Bean
 public User getUser(){this.getWoman();
 return new User();}
   @Bean("women")
   public Woman getWoman(){System.out.println("测试 @Configuration 的类办法外部调用");
 return new Woman();}
}

扫描包下的某一个 Bean

@Component
public class PropertyBean {
    private String username;
 private String password;
 public String getUsername() {return username;}
   public void setUsername(String username) {this.username = username;}
   public String getPassword() {return password;}
   public void setPassword(String password) {this.password = password;}
}

源码剖析
首先创立 ApplicationContext 对象, 创立进去的 AnnotationConfigApplicationContext 外部会持有 DefaultListableBeanFactory(实现了 BeanFactory 接口的所有办法)

public AnnotationConfigApplicationContext() {// 隐式的会调用父类的构造方法,this.beanFactory = new DefaultListableBeanFactory();
 // 此处会增加外部的一些 beanDefinition, 存储到 BeanFactory 的 beanDefinitionMap
 this.reader = new AnnotatedBeanDefinitionReader(this);
 this.scanner = new ClassPathBeanDefinitionScanner(this);
}

值得注意的是, 创立 AnnotatedBeanDefinitionReader 的过程, 会将 ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 的 beanDefinition 退出到 spring 容器中; 创立 ClassPathBeanDefinitionScanner 时, 会将 @Component 注解退出到 includeFilters.
注入 PostProcessor 的代码:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
 if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
 }
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
 }
   }
   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
 // 判断 BeanFactory 中不存在此 BeanDefinition, 增加 ConfigurationClassPostProcessor
 // ConfigurationClassPostProcessor 类负责解析解决所有 @Configuration 类,并将 BeanDefinition 注册到 BeanFactory 中。if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
 def.setSource(source);
 beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
 }
   // AutowiredAnnotationBeanPostProcessor 类负责解决 @Autowired
 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
 def.setSource(source);
 beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
 }
   // CommonAnnotationBeanPostProcessor 类负责解决 @Resource,@PostConstruct,@PreDestroy
 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
 def.setSource(source);
 beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
 }
   // 省略了局部代码
   return beanDefs;
}

注入 @Component 注解

protected void registerDefaultFilters() {
   // 此处将 Component 注入, 用于前面的辨认
 this.includeFilters.add(new AnnotationTypeFilter(Component.class));
 ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
// 省略局部代码
}

通过下面的步骤, 只是实现了 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext() 这一行代码的运行.
接下来, 要将配置类 BeanConfig, 手动注入到创立进去的 AnnotationConfigApplicationContext 中, 实际上, 是委托给了 AnnotatedBeanDefinitionReader 来进行配置类的解析工作

public void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");
 // 解析给定的 class 对象, 并存储到 beanDefinitionMap
 this.reader.register(componentClasses);
}

this.reader.register(componentClasses)这行代码, 会始终调用到doRegisterBean(), 才会开始真正的逻辑解决, 其实只做了一件事, 就是生成 BeanConfig 的 BeanDefinition, 并注入到 spring 容器中.

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
 @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
 @Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}
   abd.setInstanceSupplier(supplier);
 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
 // 设置单例还是原型
 abd.setScope(scopeMetadata.getScopeName());
 // 设置 beanName, 当传入的 name 为 null, 依照规定, 主动生成名称
 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
 // 解析局部公共的注解(@Lazy,@Primary,@DependsOn,@Role,@Description), 并将解析进去的信息填充到 beanDefinition 中
 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
 if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);
 }
         else if (Lazy.class == qualifier) {abd.setLazyInit(true);
 }
         else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));
 }
      }
   }
   if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);
 }
   }
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
 // 将解析实现的 beanDefinition 放入 beanFactory 中
 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

此时代码运行完了ac.register(BeanConfig.class), 接下来要刷新容器, 即运行ac.refresh(), 这个办法是所有 bean 进行实例化和初始化的外围, 须要重点剖析, 外围步骤如下:

  1. 获取 beanFactory
  2. 遍历 BeanDefinitionRegistryPostProcessor 接口的实现类, 调用 postProcessBeanDefinitionRegistry()办法, 将 BeanConfig 中 @ComponentScan 笼罩的 bean 的 beanDefinition 信息注册到 spring 容器中
  3. 实例化, 初始化所有非懒加载的单例 bean
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
 prepareRefresh();
 // 获取 BeanFactory, 其实是 DefaultListableBeanFactory
 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 // 设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,手动注册几个非凡的 bean
 prepareBeanFactory(beanFactory);
 try {
 // 扩大点, 能够对 beanFactory 做批改
 postProcessBeanFactory(beanFactory);
 // 实例化 BeanFactoryPostProcessor(new 利用上下文的时候注册的 beanDefinition)并调用, 作用是批改 beanDefinition 的信息
 // 例如 internalConfigurationAnnotationProcessor, 用来解析 @Configuration 注解类管辖的 beanDefinition 信息
 invokeBeanFactoryPostProcessors(beanFactory);
 // 实例化各种 BeanPostProcessors, 并注册到 beanFactory 的 beanPostProcessors 属性中
 registerBeanPostProcessors(beanFactory);
 // Initialize message source for this context.
 initMessageSource();
 // 初始化事件播送器(给 applicationEventMulticaster 赋值)
 initApplicationEventMulticaster();
 // Initialize other special beans in specific context subclasses.
 onRefresh();
 // 注册监听器(非 @EventListener 注解形式, 注册的是实现了 ApplicationListener 接口的类)
 registerListeners();
 // Instantiate all remaining (non-lazy-init) singletons.
 finishBeanFactoryInitialization(beanFactory);
 // Last step: publish corresponding event.
 finishRefresh();}
// 省略局部代码
}

首先, 剖析步骤 2

  1. 收集实现了 PriorityOrdered 接口和 BeanDefinitionRegistryPostProcessor 接口的实现类并调用 postProcessBeanDefinitionRegistry(), 其实就是调用 ConfigurationClassPostProcessor, 这个类是 spring 中的外围类, 作用是收集 @Component 注解的 Bean 信息, 解析成 BeanDefinition 注册到 spring 容器中
  2. 收集实现了 Ordered 接口和 BeanDefinitionRegistryPostProcessor 接口的实现类并调用 postProcessBeanDefinitionRegistry()
  3. 死循环收集 BeanDefinitionRegistryPostProcessor 接口的实现类 (排除了后面的) 并调用 postProcessBeanDefinitionRegistry()
  4. 调用后面所有 BeanDefinitionRegistryPostProcessor 接口的实现类的 postProcessBeanFactory()办法
  5. 收集 BeanFactoryPostProcessor 接口的实现类, 也是分成实现了 PriorityOrdered 接口,Ordered 接口和其余的三种状况, 而后调用 postProcessBeanFactory()办法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 曾经实现调用的后置处理器汇合
Set<String> processedBeans = new HashSet<>();
 // 省略局部代码
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
 // 获取实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
 String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 processedBeans.add(ppName);
 }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
 registryProcessors.addAll(currentRegistryProcessors);
 // 目前是调用 ConfigurationClassPostProcessor, 解析“配置类”的蕴含的 bean 信息,变成 beanDefinition 存入 map 中
 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
 currentRegistryProcessors.clear();
 // 获取实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 for (String ppName : postProcessorNames) {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);
 currentRegistryProcessors.clear();
 // 死循环获取其余所有的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
 // 死循环 BeanDefinitionRegistryPostProcessor 实现类的起因是, 后面的 BeanDefinitionRegistryPostProcessor 可能会注入新的实现类,
 // 所以必须从新再获取并调用一遍
 boolean reiterate = true;
 while (reiterate) {
         reiterate = false;
 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 processedBeans.add(ppName);
 reiterate = true;
 }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
 registryProcessors.addAll(currentRegistryProcessors);
 // 遍历 BeanDefinitionRegistryPostProcessor 的实现类, 调用 postProcessBeanDefinitionRegistry()
 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
 currentRegistryProcessors.clear();}
      // 遍历 BeanDefinitionRegistryPostProcessor 实现类, 调用 postProcessBeanFactory()
 // 对于 ConfigurationClassPostProcessor, 生成“配置”类 (@Configuration) 的代理类
 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
 // 遍历非 BeanDefinitionRegistryPostProcessor 实现类(本人加进来的), 调用 postProcessBeanFactory(), 根本不会执行
 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
 }
   else {// 遍历非 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! String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
 // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
 // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
 List<String> orderedPostProcessorNames = new ArrayList<>();
 List<String> nonOrderedPostProcessorNames = new ArrayList<>();
 for (String ppName : postProcessorNames) {
      // 跳过后面曾经解决过的 BeanFactoryPostProcessor 实现类
 if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 通过 beanFactory 的 getBean(), 实例化 BeanFactoryPostProcessor
 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
 }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);
 }
      else {nonOrderedPostProcessorNames.add(ppName);
 }
   }
 // 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);
   beanFactory.clearMetadataCache();}

上面重点剖析一下 ConfigurationClassPostProcessor, 其实就是剖析 processConfigBeanDefinitions(), 看看是如何将 bean 变成 beanDefinition 注册到 spring 容器

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);
 // 解析 @Component,@ComponentScan,@Import,@ImportResource 注解
 processConfigBeanDefinitions(registry);
}

接下来, 看看 processConfigBeanDefinitions()的实现逻辑, 次要流程如下:

  1. 获取容器中所有曾经注册进来的 beanName, 其实此时只有一个手动注册进来的 BeanConfig, 其余的全部都是 spring 本人注册的
  2. 筛选出 @Configuration 注解的类, 其实就是 BeanConfig
  3. 创立 ConfigurationClassParser, 是个解析器, 作用是解析 @ComponentScan 注解
  4. 进行 parse(), 将 @ComponentScan 指定的包下所有 @Component 注解的 bean 变成 beanDefinitiion 注册到 spring 容器中, 同时对每一个 @Component 注解的 bean, 包装成 ConfigurationClass(封装了注解信息 metadata,beanName,beanMethods 和 importedResources), 注册到 ConfigurationClassParser 中的 configurationClasses 属性
  5. 遍历 configurationClasses 中的 ConfigurationClass, 解决 @Bean,@Import 和 @ImportResource 注解, 其中,@Bean 和 @Import 会生成 beanDefinition 注册到 spring 容器中
  6. 找出步骤 4 中注册进来的 beanDefinition, 判断这些 beanDefinition 是否存在 @Configuration,@ComponentScan,@Component,@ImportResource 和 @Import 注解(至于为什么没有在步骤 3 中扫描到这些 beanDefinition, 起因是这些 bean 不在 @ComponentScan 所指定的包下), 若判断为 true, 则将反复步骤 3~6

通过以上步骤之后,@ComponentScan 指定包下的 bean 都曾经变成 beanDefinition 注册到 spring 容器中了

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
 String[] candidateNames = registry.getBeanDefinitionNames();
 // 筛选具备 @Component,@ComponentScan,@Import,@ImportResource 注解信息的 BeanDefinition
 for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);
 if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class:" + beanDef);
 }
      }
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {// 若是无 xml 形式配置的, 此处只会筛选出 @Configuration 注解的类(即 ac.register(BeanConfig.class))
 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
 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();
 }
   // 实例化 ConfigurationClassParser 时, 会 new 一个 ComponentScanAnnotationParser 对象,
 // 用来解析 @ComponentScan 注解对应的 bean 信息
 ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
 this.resourceLoader, this.componentScanBeanNameGenerator, registry);
 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
 Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
 do {
      // 解析配置类, 变成 beanDefinition 退出 beanFactory 的 beanDefinitionMap 中
 // 最终的解析过程是委托给了一个实例化的 ClassPathBeanDefinitionScanner 类
 // 解析进去的配置类, 存储在 parser 的 configurationClasses 属性中
 parser.parse(candidates);
 parser.validate();
 // 失去所有配置类的 bean 信息
 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());
 }
      // 通过 ConfigurationClass 加载更多的 BeanDefinition, 通过后面 parser.parse(candidates), 解析了 @bean 注解并保留在 ConfigurationClass 的 beanMethods
 // 再通过 beanMethods, 生成 BeanDefinition 信息并注册到 beanDefinitionMap 中
 // 将 @ImportResource 注解的资源引入 spring
 // 将 @Import 注解的类, 生成 BeanDefinition 信息并注册到 beanDefinitionMap 中
 this.reader.loadBeanDefinitions(configClasses);
 alreadyParsed.addAll(configClasses);
 candidates.clear();
 // 如果进入到上面的代码中, 则示意原工程中有 @Configuration 注解的配置类
 if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();
 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())) {// 相似递归, 若 @Configuration 注解的配置类管辖了另外的 @Configuration(不在 oldCandidateNames 汇合中), 再次循环
 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();}
}

上面重点剖析一下步骤 4, 解析 @ComponentScan 的过程, 实际上调用的是 processConfigurationClass()办法, 次要是循环的调用 doProcessConfigurationClass(), 并且每次跳出循环, 都会将 configClass 注册到属性 configurationClasses 中

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}
   ConfigurationClass existingClass = this.configurationClasses.get(configClass);
 if (existingClass != null) {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);
 }
   }
   // 递归的解决配置类 configClass 及其所继承的父类
 // 从以后配置类 configClass 开始向上沿着类继承构造逐层执行 doProcessConfigurationClass(),
 // 直到遇到的父类是由 Java 提供的类完结循环
 SourceClass sourceClass = asSourceClass(configClass, filter);
 do {sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
 }
   while (sourceClass != null);
 // 须要被解决的配置类 configClass 曾经被剖析解决,将它记录到已解决配置类记录
 this.configurationClasses.put(configClass, configClass);
}

真正解决 @ComponentScan 的代码逻辑, 步骤如下:

  1. 收集所有被 @Component 注解并且在 @ComponentScan 指定的包下的 bean, 转换成 beanDefinition 注册到 spring 容器中
  2. 遍历步骤 1 中的 beanDefinition, 找出存在 @Configuration,@ComponentScan,@Component,@ImportResource 和 @Import 注解信息的 beanDefinition, 调用 parse()办法, 实际上, 再次调用次要是为了解析 @Bean,@ComponentScan,@ImportResource 和 @Import 注解, 目标也是为了注册这些注解代表的 beanDefinition
  3. 解决 @Import 注解
  4. 解决 @ImportResource 注解
  5. 解决 @Bean 注解

// TODO 解析的流程画个图

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
      throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// 递归解决外部类(外部类也有 @Component 注解, 须要注册到容器中)
 processMemberClasses(configClass, sourceClass, filter);
 }
   // 解决 @PropertySource 注解
 for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,
 org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);
 }
      else {logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
               "]. Reason: Environment must implement ConfigurableEnvironment");
 }
   }
   // 解决 @ComponentScan 注解
 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
 if (!componentScans.isEmpty() &&
         !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {
         // 此 configClass 存在 @ComponentScan 注解, 扫描获取 basePackages 的所有 bean 信息
 Set<BeanDefinitionHolder> scannedBeanDefinitions =
               this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
 // Check the set of scanned definitions for any further config classes and parse recursively if needed
 for (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
 if (bdCand == null) {bdCand = holder.getBeanDefinition();
 }
            // 判断通过 @ComponentScan 扫描新退出的 bdCand, 是否存在 @Configuration,@ComponentScan,@Component,@ImportResource,@Import 注解,
 // 若有, 则再次进入配置类的解析解决流程
 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());
 }
         }
      }
   }
   // 解决 @Import 注解, 给 configClass 退出 ImportBeanDefinitionRegistrar, 后续会调用
 // getImports(), 遍历并递归获取 sourceClass 的所有注解中蕴含 @import 注解的 value 值
 processImports(configClass, sourceClass, getImports(sourceClass), filter, 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 注解,获取注解的办法的相干元数据,比方办法名、所在类全名、返回类型、是否动态、是否不可笼罩等等信息
 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
 for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
 }
   // Process default methods on interfaces
 processInterfaces(configClass, sourceClass);
 // Process superclass, if any
 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();}
   }
   // No superclass -> processing is complete
 return null;
}
退出移动版