Spring BeanDefinition收集过程示例详解

 更新时间:2023年08月08日 11:27:45   作者:毛方云  
这篇文章主要为大家介绍了Spring BeanDefinition收集过程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

以注解方式说明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进行实例化和初始化的核心,需要重点分析,核心步骤如下:

获取beanFactory

遍历BeanDefinitionRegistryPostProcessor接口的实现类,调用postProcessBeanDefinitionRegistry()方法,将BeanConfig中@ComponentScan覆盖的bean的beanDefinition信息注册到spring容器中

实例化,初始化所有非懒加载的单例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();
 }
// 省略部分代码
}

分析步骤

  • 收集实现了PriorityOrdered接口和BeanDefinitionRegistryPostProcessor接口的实现类并调用postProcessBeanDefinitionRegistry(),其实就是调用ConfigurationClassPostProcessor,这个类是spring中的核心类,作用是收集@Component注解的Bean信息,解析成BeanDefinition注册到spring容器中
  • 收集实现了Ordered接口和BeanDefinitionRegistryPostProcessor接口的实现类并调用postProcessBeanDefinitionRegistry()
  • 死循环收集BeanDefinitionRegistryPostProcessor接口的实现类(排除了前面的)并调用postProcessBeanDefinitionRegistry()
  • 调用前面所有BeanDefinitionRegistryPostProcessor接口的实现类的postProcessBeanFactory()方法
  • 收集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()实现逻辑

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

  • 获取容器中所有已经注册进来的beanName,其实此时只有一个手动注册进来的BeanConfig,其他的全部都是spring自己注册的
  • 筛选出@Configuration注解的类,其实就是BeanConfig
  • 创建ConfigurationClassParser,是个解析器,作用是解析@ComponentScan注解
  • 进行parse(),将@ComponentScan指定的包下所有@Component注解的bean变成beanDefinitiion注册到spring容器中,同时对每一个@Component注解的bean,包装成ConfigurationClass(封装了注解信息metadata,beanName,beanMethods和importedResources),注册到ConfigurationClassParser中的configurationClasses属性
  • 遍历configurationClasses中的ConfigurationClass,处理@Bean,@Import和@ImportResource注解,其中,@Bean和@Import会生成beanDefinition注册到spring容器中
  • 找出步骤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的代码逻辑,步骤如下:

  • 收集所有被@Component注解并且在@ComponentScan指定的包下的bean,转换成beanDefinition注册到spring容器中
  • 遍历步骤1中的beanDefinition,找出存在@Configuration,@ComponentScan,@Component,@ImportResource和@Import注解信息的beanDefinition,调用parse()方法,实际上,再次调用主要是为了解析@Bean,@ComponentScan,@ImportResource和@Import注解,目的也是为了注册这些注解代表的beanDefinition
  • 处理@Import注解
  • 处理@ImportResource注解
  • 处理@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;
}

以上就是Spring BeanDefinition收集过程示例详解的详细内容,更多关于Spring BeanDefinition收集过程的资料请关注脚本之家其它相关文章!

相关文章

  • Java排序算法总结之插入排序

    Java排序算法总结之插入排序

    这篇文章主要介绍了Java排序算法总结之插入排序,较为详细的分析了插入排序的原理与java实现技巧,需要的朋友可以参考下
    2015-05-05
  • java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP)

    java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP)

    这篇文章主要介绍了java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP),非常具有实用价值,需要的朋友可以参考下
    2018-08-08
  • Docker使用Dockerfile自定义镜像方式

    Docker使用Dockerfile自定义镜像方式

    这篇文章主要介绍了Docker使用Dockerfile自定义镜像方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java显示程序包不存在的三种解决方法总结

    Java显示程序包不存在的三种解决方法总结

    在Java开发中,有时会遇到“程序包javax.servlet不存在”等错误提示,这通常是因为缺少必要的库或依赖项,这篇文章主要给大家介绍了关于Java显示程序包不存在的三种解决方法,需要的朋友可以参考下
    2024-07-07
  • Springboot整合logback多节点日志文件加端口号区分的操作方法

    Springboot整合logback多节点日志文件加端口号区分的操作方法

    这篇文章主要介绍了Springboot整合logback多节点日志文件加端口号区分的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • Java 虚拟机栈详解分析

    Java 虚拟机栈详解分析

    在线程创建时,JVM会为每个线程创建一个单独的栈空间。JVM的栈内存不需要是连续的。JVM在栈上会进行两个操作:压入和弹出栈帧。对于一个特定的线程来说,栈被称为运行时栈。这个线程调用的每个方法会被存储在响应的运行时栈里,包括了参数,局部变量,计算媒介和其他数据
    2021-11-11
  • Java如何实现Word文档分栏效果

    Java如何实现Word文档分栏效果

    这篇文章主要介绍了Java如何实现Word文档分栏效果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 锁超时发现parallelStream并行流线程上下文坑解决

    锁超时发现parallelStream并行流线程上下文坑解决

    这篇文章主要为大家介绍了锁超时发现parallelStream并行流线程上下文坑解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • mybatis的动态SQL和模糊查询实例详解

    mybatis的动态SQL和模糊查询实例详解

    这篇文章主要给大家介绍了关于mybatis的动态SQL和模糊查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • SpringCloud集成Eureka并实现负载均衡的过程详解

    SpringCloud集成Eureka并实现负载均衡的过程详解

    这篇文章主要给大家详细介绍了SpringCloud集成Eureka并实现负载均衡的过程,文章通过代码示例和图文讲解的非常详细,对大家的学习或工作有一定的参考价值,需要的朋友可以参考下
    2023-11-11

最新评论