优秀的编程知识分享平台

网站首页 > 技术文章 正文

Spring源码分析(二)——Bean定义阶段

nanyue 2024-09-07 16:43:54 技术文章 7 ℃

一、前言

我们上一篇知道了spring是如何对bean的生命周期进行定义的,这一篇我们具体分析一下bean定义阶段是如何将我们的bean扫描出来的;

注:只分析核心流程;

二、源码流程分析准备

在进行源码分析时我们需要了解二个比较核心的概念:什么是beanDefifinition、什么容器

1、什么是BeanDefifinition?

BeanDefinition——spring bean的建模对象;

那么什么是spring bean的建模对象呢?就是把一个bean实例化出来的模型对象?有人会问把一个bean实例化出来有Class就行了啊,Class也就是我们通常说的类对象,就是一个普通对象的建模对象,那么为什么spring不能用Class来建立bean呢?很简单,因为Class无法完成bean的抽象,比如bean的作用域,bean的注入模型,bean是否是懒加载等等信息,Class是无法抽象出来的,故而需要一个BeanDefinition类来抽象这些信息,以便于spring能够完美的实例化一个bean;

BeanDefinition是一个接口,我们可以看一下他的抽象实现:AbstractBeanDefinition,里面有许多属性定义了bean的一个状态;

Spring实例化简图

当spring容器启动的时候会去调用ConfigurationClassPostProcessor这个bean工厂的后置处理器完成扫描,每个扫描出来的类会构建成BeanDefinition,再对BeanDefinition的对象中赋值,如:scope,lazy,dependsOn等等信息,最后put到beanDefintionMap,后面才会去实例化。

2、什么是容器?

容器是一个抽象的概念,是由一些列组件组合在一起完成spring bean管理的工作;容器主要有两种分别是BeanFactory和ApplicationContext;

beanFactory是一个简单的容器,能完成ban的实例化,bean的依赖注入;

早期开发应用程序资源有限,使用beanFactory可以节省很大的资源;说个最简单的比方beanFactory当中的bean都是懒加载的,但是随着互联网的发展现在的资源已经没有那么紧张了(比如内存),绝大部分情况下都是用ApplicationContext这个容器,他们主要区别在于ApplicationContext的功能比较丰富,支持国际化、支持事件发布、支持BeanPostProcessor的自动注册;至于他们之间的细节区别需要我们对spring有非常深入的理解;


该容器当中有一个非常重要的组件DefaultListableBeanFactory对象;这个对象当中有一个组件beanDefifinitionMap主要来存储所有扫描出来的beandefifinition;

三、源码分析

AnnotationConfigApplicationContext
				context = new AnnotationConfigApplicationContext();
		context.register(ContextConfig.class);
		context.refresh();

我们先从容器AnnotationConfigApplicationContext初始化开始分析;

AnnotationConfigApplicationContext初始化方法做了什么?

public AnnotationConfigApplicationContext() {
        /**
         * BeanDefinition渲染器
         * 1、具备解析一个类的功能,如:注册我们的配置类
         * 2、可用于编程式动态注册一个带注解的bean
         */
        /** 注册spring内置BeanDefinition */
		this.reader = new AnnotatedBeanDefinitionReader(this);
        /**
         * 完成spring的扫描功能,将打了注解的bean扫描出来
         * 注:spring内部完成扫描功能并不是用的这个对象,而是在扫描的时候又new了一个新的ClassPathBeanDefinitionScanner对象
         * 构造方法中会添加默认过滤器
         */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

里面最重要的就是会添加一些内置的BeanDefinition去完成类的扫描和属性的自动注入,注解处理等;

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");
   this.registry = registry;
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
       /**
        * 注册了spring官方内置的BeanDefinition
        */
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

这里会注册5个内置的BeanDefinition

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);

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

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

   // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
   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));
   }

   // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
   if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition();
      try {
         def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
               AnnotationConfigUtils.class.getClassLoader()));
      }
      catch (ClassNotFoundException ex) {
         throw new IllegalStateException(
               "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
      }
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
   }

   return beanDefs;
}
// 底层实际是将我们传递进去的ContextConfig构造成BeanDefinition放入beanDefifinitionMap中
context.register(ContextConfig.class);

此时beanDefifinitionMap中的数据结构为下图所示:

后面执行到org.springframework.context.support.AbstractApplicationContext#refresh方法中去,这个方法会先将我们的类扫描出来再进行初始化等操作,我们这一篇只会分析他是如何完成扫描的;

下面这个方法很重要,在里面直接大部分bean扫描出来了,而且里面会调用内置BeanDefinition:org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry进行配置类的解析,最重要的是会解析我们配置的扫描路径进行类的扫描;

我们先分析BeanFactoryPostProcessor的实例化和执行流程,后续在分析ConfigurationClassPostProcessor,先看源码,后面会进行总结;

/**
    * 直接实现了BeanFactoryPostProcessor接口,或者实现了BeanDefinitionRegistryPostProcessor接口
    * @param beanFactory
    * @param beanFactoryPostProcessors
    */
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
       /**
        * 存放已经处理完的BeanFactoryPostProcessor 以及他的子类 BeanDefinitionRegistryPostProcessor
        * 通过set来防止重复执行
        * 注:不包含API提供
        */
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

           /**
            * 如果你在容器创建的时候通过api添加了BeanFactoryPostProcessor则会进行执行
            * 说明通过api接口调用添加的BeanFactoryPostProcessor执行时机是最高的
            */
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            /** 执行子类BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法 */
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            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.
           /**
            * 根据类型从BeanDefinitionMap中查询对应的名字
            * 这里就会获取到内置BeanDefinition和我们注册的配置类
            */
           String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
          /** 判断是否实现了PriorityOrdered接口 */
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                   /**
                    * 实现了实例化出来,放入当前需要执行的集合当中
                    * 说明实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的执行排序在第二位
                    */
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            // 执行完成,放入set集合,防止重复执行
            processedBeans.add(ppName);
         }
      }
      // 排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
           /**
            * 合并,下面代码只是遍历执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
            * 其实我们点击进去会发现BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口
            * 所以此时相当于我们只是执行了子类的接口,后续还需要执行父类的接口,所以先添加进去
            * 说明是先执行子类的方法,再统一执行父类的方法
            */
      registryProcessors.addAll(currentRegistryProcessors);
      /** 遍历执行刚刚加入的BeanDefinitionRegistryPostProcessor */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      // 清空集合,下次使用
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
           /**
            * 获取所有实现了BeanDefinitionRegistryPostProcessor的子类
            * 这里为什么重新拿一次,直接使用之前拿出来的不行吗?
            * 不行,因为刚刚已经有BeanDefinitionRegistryPostProcessor执行; ,可能在执行的时候注册新的BeanDefinitionRegistryPostProcessor,所以需要重新拿一次
            */
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
               /**
                * 此时会判断是否已经执行过了,并且实现了Ordered接口
                * 说明实现了Ordered接口的BeanDefinitionRegistryPostProcessor是在第三梯队执行的
                */
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            /** 实例化bean,并且放入currentRegistryProcessors */
             currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                   // 放入processedBeans防止重复执行
             processedBeans.add(ppName);
         }
      }
      // 排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      /** 加入待执行父类的方法的集合 */
      registryProcessors.addAll(currentRegistryProcessors);
      /** 遍历执行刚刚加入的BeanDefinitionRegistryPostProcessor */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
           // 清空集合,下次使用
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      boolean reiterate = true;
      while (reiterate) {
          /** 置为false,如果后续没有修改则说明所有的BeanDefinitionRegistryPostProcessor已经处理完了 */
         reiterate = false;
               /**
                * 获取所有实现了BeanDefinitionRegistryPostProcessor的子类
                * 这里重新拿一次也是为怕有新注册的BeanDefinitionRegistryPostProcessor
                */
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
                   /**
                    * 这里就直接判断是否已经处理,执行所有剩余的BeanDefinitionRegistryPostProcessor
                    */
            if (!processedBeans.contains(ppName)) {
                /** 未处理则实例化放入currentRegistryProcessors */
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               // 放入processedBeans防止重复执行
               processedBeans.add(ppName);
                       /**
                        * 如果还有待执行的BeanDefinitionRegistryPostProcessor
                        * 可能在执行的时候还会加入BeanDefinitionRegistryPostProcessor,因此还需要循环进行处理
                        */
               reiterate = true;
            }
         }
               // 排序
         sortPostProcessors(currentRegistryProcessors, beanFactory);
               /** 加入待执行父类的方法的集合 */
         registryProcessors.addAll(currentRegistryProcessors);
               /** 遍历执行刚刚加入的BeanDefinitionRegistryPostProcessor */
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
               // 清空集合,下次使用
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
           /**
            * 调用所有找出来的实现了子类的父类方法
            * 刚刚执行了子类方法,在这里统一执行父类方法
            */
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      /** 调用找出来的所有通过api提供的直接实现父类的方法 */
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      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.
       /**
        * 存储所有实现了BeanFactoryPostProcessor和priorityOrdered接口的类
        */
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
       /**
        * 存储所有实现了BeanFactoryPostProcessor和ordered接口的类
        */
   List<String> orderedPostProcessorNames = new ArrayList<>();
       /**
        * 存储所有只实现了BeanFactoryPostProcessor接口的类
        */
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
       // 如果已处理就什么都不做
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      // 判断是否实现了PriorityOrdered接口
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
          // 实例化并放入集合
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      // 判断是否实现Ordered接口
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
          // 不实例化,只是将字符串放入
         orderedPostProcessorNames.add(ppName);
      }
      else {
               // 不实例化,只是将字符串放入
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
       // 对实现了priorityOrdered接口的类进行排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   /** 执行父类方法 */
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
       /** 存储实现了ordered接口类的实例化数据 */
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
       /** 实例化所有实现了ordered接口的类 */
       for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
       /** 执行父类方法 */
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
       /**
        * 对没有实现priorityOrdered接口也没有实现ordered接口的类进行实例化
        */
   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();
}

BeanFactoryPostProcessor执行时机总结

那我们自己的写的类是什么时候扫描出来的呢?

在BeanFactoryPostProcessor的执行顺序中第二阶段会执行Spring内置的ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,因为他实现了PriorityOrdered接口;

在这个方法里面会解析我们扫描的包路径进行类扫描;

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
   String[] candidateNames = registry.getBeanDefinitionNames();

       /**
        * 因为这个类的执行顺序比较早,所以这里只会调用内置的和我们提供的配置类
        */
   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)) {
         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
   /** 获取bean名字生成策略 */
       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);

   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
   Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
   do {
       /** 解析配置类 */
      parser.parse(candidates);
      parser.validate();

      /** 已经解析好的配置类 */
      Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
      configClasses.removeAll(alreadyParsed);

      // Read the model and create bean definitions based on its content
      if (this.reader == null) {
         this.reader = new ConfigurationClassBeanDefinitionReader(
               registry, this.sourceExtractor, this.resourceLoader, this.environment,
               this.importBeanNameGenerator, parser.getImportRegistry());
      }
      this.reader.loadBeanDefinitions(configClasses);
      alreadyParsed.addAll(configClasses);

      candidates.clear();
      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())) {
                  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();
   }
}

后面比较重要的方法则是这个,具体解析配置类,为什么是配置类呢?其实在spring里一切类其实都是当做配置类进行处理的;


这里的代码我们需要看的就是this.componentScanParser.parse这个方法,这里里面会对ComponentScan注解进行解析,识别里面的包路径进行类扫描

protected final SourceClass doProcessConfigurationClass(
      ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
      throws IOException {

    /** 判断是否加了Component注解 */
   if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
      // Recursively process any member (nested) classes first
           /** 处理内部类 */
      processMemberClasses(configClass, sourceClass, filter);
   }

   // Process any @PropertySource annotations
   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");
      }
   }

   // Process any @ComponentScan annotations
       /** 如果加了扫描注解则进行扫描操作 */
   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) {
         // The config class is annotated with @ComponentScan -> perform the scan immediately

               /** 解析配置类,完成扫描 */
               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();
            }
            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
               parse(bdCand.getBeanClassName(), holder.getBeanName());
            }
         }
      }
   }

   // Process any @Import annotations
       /** 处理Import注解 */
   processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

   // Process any @ImportResource annotations
   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);
      }
   }

   // Process individual @Bean methods
       /** 处理加了Bean注解的方法 */
   Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
   for (MethodMetadata methodMetadata : beanMethods) {
      configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
   }

   // Process default methods on interfaces
       /** 解析接口当中默认的方法是否加了bean注解,注:其他的配置信息写在接口里面是不起作用的 */
   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;
}



/** 处理Import注解 */
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {

				    /** 判断是否实现了ImportSelector接口 */
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						/** 获取对应的Class对象 */
                        Class<?> candidateClass = candidate.loadClass();
                        /** 将candidateClass Class对象实例化成对象 */
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);
						/** 断言处理 */
						Predicate<String> selectorFilter = selector.getExclusionFilter();
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						/** 判断是否需要延迟加载 */
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
						    /** 调用selectImports方法获取需要Import的类的绝对名称 */
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							/** 将字符串的类构造为SourceClass放入集合中 */
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}

					/** 判断是否实现了ImportBeanDefinitionRegistrar接口 */
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}

					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}

注意看方法名,这里需要注意一下,这里的扫描器是重新构造的,并不是使用的容器AnnotationConfigApplicationContext初始化的时候构建的那个扫描器;

org.springframework.context.annotation.ComponentScanAnnotationParser#parse

/**
    * 解析配置类上面的componentScan注解
    * @param componentScan
    * @param declaringClass
    * @return
    */
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
   /** 实例化扫描器 */
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
         componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

    /** 判断是否配置了名字生成策略 */
   Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");

   /** 判断名字生成策略是否为默认的 */
   boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);

   /** 如果配置了名字生成策略 */
   scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
         BeanUtils.instantiateClass(generatorClass));

   ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
   if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
      scanner.setScopedProxyMode(scopedProxyMode);
   }
   else {
      Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
      scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
   }

   scanner.setResourcePattern(componentScan.getString("resourcePattern"));

   /** 处理配置注入过滤器 */
   for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
      for (TypeFilter typeFilter : typeFiltersFor(filter)) {
         scanner.addIncludeFilter(typeFilter);
      }
   }
   /** 处理排除过滤器 */
   for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
      for (TypeFilter typeFilter : typeFiltersFor(filter)) {
         scanner.addExcludeFilter(typeFilter);
      }
   }

   /** 当前配置类是否为懒加载 */
   boolean lazyInit = componentScan.getBoolean("lazyInit");
   if (lazyInit) {
      scanner.getBeanDefinitionDefaults().setLazyInit(true);
   }

   /** 包路径集合 */
   Set<String> basePackages = new LinkedHashSet<>();
   String[] basePackagesArray = componentScan.getStringArray("basePackages");
   for (String pkg : basePackagesArray) {
      String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
            ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
      Collections.addAll(basePackages, tokenized);
   }
   for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
      basePackages.add(ClassUtils.getPackageName(clazz));
   }

   if (basePackages.isEmpty()) {
      basePackages.add(ClassUtils.getPackageName(declaringClass));
   }

   /** 添加当前配置类过滤器 */
   scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
      @Override
      protected boolean matchClassName(String className) {
         return declaringClass.equals(className);
      }
   });
   /** 开始扫描 */
   return scanner.doScan(StringUtils.toStringArray(basePackages));
}

根据传入的包路径集合进行解析,这里的包路径是可以有多个的,因为ComponentScan注解是可以设置多个包路径的;

这里会将扫描出来的BeanDefinition放入beanDefinitionMap中,后续BeanFactoryPostProcessor执行流程时如果我们写的类用实现了这个接口则会获取出来进行执行;

org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
   Assert.notEmpty(basePackages, "At least one base package must be specified");
   Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
   for (String basePackage : basePackages) {

       /** 根据包名扫描符合规则的BeanDefinition */
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

      for (BeanDefinition candidate : candidates) {
          /** 设置bean的作用域 */
         ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
         candidate.setScope(scopeMetadata.getScopeName());
         /** 生成bean的名字 */
         String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
         if (candidate instanceof AbstractBeanDefinition) {
            postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
         }
         if (candidate instanceof AnnotatedBeanDefinition) {
             /** 处理公共注解逻辑,这里会对BeanDefinition是否懒加载、bean角色、描述等进行赋值 */
            AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
         }
         /** 判断是否已经注册 */
         if (checkCandidate(beanName, candidate)) {
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
            definitionHolder =
                  AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            beanDefinitions.add(definitionHolder);
            /** 将BeanDefinition注册到beanDefinitionMap中 */
            registerBeanDefinition(definitionHolder, this.registry);
         }
      }
   }
   return beanDefinitions;
}

这里是具体的扫描动作,会将获取的文件流解析成BeanDefinition

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
   Set<BeanDefinition> candidates = new LinkedHashSet<>();
       /**
        * 通过包名获取包所在的绝对路径得到一个文件对象_流
        */
   try {
      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;
      /** 通过绝对路径获取到InputStreamSource集合 */
      Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
      boolean traceEnabled = logger.isTraceEnabled();
      boolean debugEnabled = logger.isDebugEnabled();
      for (Resource resource : resources) {
         if (traceEnabled) {
            logger.trace("Scanning " + resource);
         }
         try {
             /** 将文件流封装成MetadataReader */
            MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);

            /** 判断是否被排除、是否加了必要的注解 */
            if (isCandidateComponent(metadataReader)) {
               ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
               sbd.setSource(resource);
               /** 判断是否是抽象类,是否是接口 */
               if (isCandidateComponent(sbd)) {
                  if (debugEnabled) {
                     logger.debug("Identified candidate component class: " + resource);
                  }
                  candidates.add(sbd);
               }
               else {
                  if (debugEnabled) {
                     logger.debug("Ignored because not a concrete top-level class: " + resource);
                  }
               }
            }
            else {
               if (traceEnabled) {
                  logger.trace("Ignored because not matching any filter: " + resource);
               }
            }
         }
         catch (FileNotFoundException ex) {
            if (traceEnabled) {
               logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
            }
         }
         catch (Throwable ex) {
            throw new BeanDefinitionStoreException(
                  "Failed to read candidate component class: " + resource, ex);
         }
      }
   }
   catch (IOException ex) {
      throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
   }
   return candidates;
}

至此,所有的类(不包含特殊生成的类)就被扫描出来了,当然这里我们只关注扫描逻辑,对一些代码细节没有分析,如:如果同一级别的BeanDefinition,执行顺序是怎样的,如何排序;bean的生成策略是怎样的,可不可以自己指定;java的环境变量和系统的环境变量怎么获取的;全配置类和半配置类有什么区别;

后续会单开一篇去将上面所讲到的细节部分进行解答,有什么不对的地方欢迎指出,谢谢大家观看

最近发表
标签列表