Spring IOC源码(六):IOC容器之 beanFactory后置处理器

1、源码解析

  invokeBeanFactoryPostProcessors(beanFactory)调用各种beanFactory处理器,该方法主要实例化所有已经注册的beanFactoryPostProcessor。

1.1、BeanFactory后置处理核心流程图

1.2、BeanFactory后置处理核心逻辑

  AbstractApplicationContext#invokeBeanFactoryPostProcessors 核心伪代码

1 // 根据特定的顺序,实例化并且调用已经注册了的beanFactoryPostProcessor
2 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
3    // 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值,
4    // 并且实例化调用执行所有已经注册的beanFactoryPostProcessor
5    // 默认情况下,通过getBeanFactoryPostProcessors()来获取已经注册的BFPP
6    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
7    // ...
8 }

  核心处理是在PostProcessorRegistrationDelegate委托类的invokeBeanFactoryPostProcessors方法,方法有些长但核心处理逻辑很明确。

  1 // 处理BeanFactoryPostProcessors
  2 public static void invokeBeanFactoryPostProcessors(
  3       ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  4 
  5    // 无论是什么情况,优先执行BeanDefinitionRegistryPostProcessors
  6    // 将已经执行过的BFPP存储在processedBeans中,防止重复执行
  7    Set<String> processedBeans = new HashSet<>();
  8 
  9    // 判断beanfactory是否是BeanDefinitionRegistry类型,此处是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,所以为true
 10    if (beanFactory instanceof BeanDefinitionRegistry) {
 11       // 转换为BeanDefinitionRegistry类型
 12       BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
 13       // 存放BeanFactoryPostProcessor的集合
 14       List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
 15       // 存放BeanDefinitionRegistryPostProcessor的集合
 16       List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
 17 
 18       // 首先处理入参中的beanFactoryPostProcessors,遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor区分开
 19       for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
 20          // 如果是BeanDefinitionRegistryPostProcessor类型
 21          if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
 22              // 类型转换
 23             BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
 24             // 直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
 25             registryProcessor.postProcessBeanDefinitionRegistry(registry);
 26             // 添加到registryProcessors,用于后续执行postProcessBeanFactory方法
 27             registryProcessors.add(registryProcessor);
 28          }
 29          else {
 30             // 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行postProcessBeanFactory方法
 31             regularPostProcessors.add(postProcessor);
 32          }
 33       }
 34       
 35       // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
 36       List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
 37 
 38       // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
 39       // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
 40       String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 41       // 遍历处理所有符合规则的postProcessorNames
 42       for (String ppName : postProcessorNames) {
 43          // 检测是否实现了PriorityOrdered接口
 44          if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
 45             // 获取beanName对应的bean实例,添加到currentRegistryProcessors中
 46             currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 47             // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
 48             processedBeans.add(ppName);
 49          }
 50       }
 51       // 按照优先级进行排序操作
 52       sortPostProcessors(currentRegistryProcessors, beanFactory);
 53       // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
 54       registryProcessors.addAll(currentRegistryProcessors);
 55       // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
 56       invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
 57       // 执行完毕之后,清空currentRegistryProcessors
 58       currentRegistryProcessors.clear();
 59 
 60       // 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类
 61       // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,
 62       // 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessor
 63       postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 64       for (String ppName : postProcessorNames) {
 65          // 检测是否实现了Ordered接口,并且还未执行过
 66          if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
 67             // 获取名字对应的bean实例,添加到currentRegistryProcessors中
 68             currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 69             // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
 70             processedBeans.add(ppName);
 71          }
 72       }
 73       // 按照优先级进行排序操作
 74       sortPostProcessors(currentRegistryProcessors, beanFactory);
 75       // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
 76       registryProcessors.addAll(currentRegistryProcessors);
 77       // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
 78       invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
 79       // 执行完毕之后,清空currentRegistryProcessors
 80       currentRegistryProcessors.clear();
 81 
 82       // 最后,调用所有剩下的BeanDefinitionRegistryPostProcessors
 83       boolean reiterate = true;
 84       while (reiterate) {
 85          reiterate = false;
 86          // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
 87          postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 88          // 遍历执行
 89          for (String ppName : postProcessorNames) {
 90             // 跳过已经执行过的BeanDefinitionRegistryPostProcessor
 91             if (!processedBeans.contains(ppName)) {
 92                // 获取名字对应的bean实例,添加到currentRegistryProcessors中
 93                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 94                // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
 95                processedBeans.add(ppName);
 96                reiterate = true;
 97             }
 98          }
 99          // 按照优先级进行排序操作
100          sortPostProcessors(currentRegistryProcessors, beanFactory);
101          // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
102          registryProcessors.addAll(currentRegistryProcessors);
103          // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
104          invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
105          // 执行完毕之后,清空currentRegistryProcessors
106          currentRegistryProcessors.clear();
107       }
108 
109        // 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
110       invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
111       // 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
112       invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
113    }
114 
115    else {
116       // 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法
117       invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
118    }
119 
120    // 找到所有实现BeanFactoryPostProcessor接口的类
121    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
122 
123    
124    // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
125    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
126    // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
127    List<String> orderedPostProcessorNames = new ArrayList<>();
128    // 用于存放普通BeanFactoryPostProcessor的beanName
129    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
130    // 遍历postProcessorNames,将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
131    for (String ppName : postProcessorNames) {
132       // 跳过已经执行过的BeanFactoryPostProcessor
133       if (processedBeans.contains(ppName)) {
134       }
135       // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
136       else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
137          priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
138       }
139       // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNames
140       else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
141          orderedPostProcessorNames.add(ppName);
142       }
143       else {
144          // 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames
145          nonOrderedPostProcessorNames.add(ppName);
146       }
147    }
148 
149   // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序
150    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
151    // 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
152    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
153 
154    // 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合
155    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
156    // 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合
157    for (String postProcessorName : orderedPostProcessorNames) {
158       // 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中
159       orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
160    }
161    // 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作
162    sortPostProcessors(orderedPostProcessors, beanFactory);
163    // 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
164    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
165 
166   // 最后,创建存放普通的BeanFactoryPostProcessor的集合
167    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
168    // 遍历存放实现了普通BeanFactoryPostProcessor名字的集合
169    for (String postProcessorName : nonOrderedPostProcessorNames) {
170       // 将普通的BeanFactoryPostProcessor添加到集合中
171       nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
172    }
173    // 遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
174    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
175 
176     // 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)
177    // 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符
178    beanFactory.clearMetadataCache();
179 }
核心流程:
1、创建processedBeans用来存储已处理过的BFPP(BeanFactoryPostProcessor);
2、若beanfactory为BeanDefinitionRegistry类型。
  2.1、对beanFacoty做类型转换,创建集合regularPostProcessors存放beanFactoryPostProcessor(BFPP)类型,集合registryProcessors存放BeanDefinitionRegistryPostProcessor(BDRPP)类型。
  2.2、遍历入参中的集合beanFactoryPostProcessors,若不为空并且为BDRPP类型,优先执行BDRPP接口中的postProcessBeanDefinitionRegistry方法,并记录到registryProcessors集合中;若不为BDRPP类型,则记录到regularPostProcessors集合。
  2.3、创建集合currentRegistryProcessors,用于记录当前要执行的BDRPP类型对象。
  2.4、获取所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,并记录在集合postProcessorNames中,筛选出实现了PriorityOrdered接口的BDRPP
  2.5、获取BDRPP实例并记录到currentRegistryProcessors集合,并将BDRPP的名称记录到processedBeans集合中,避免重复执行;对currentRegistryProcessors集合做排序操作,调用invokeBeanDefinitionRegistryPostProcessors执行BDRPP的后置处理,(其中ConfigurationClassPostProcessor就是在该步骤处理的,用于解析@Configuration、@Bean、@Component、@ComponentScan等注解的BeanDefinition信息),处理完成后清空currentRegistryProcessors集合。
  2.6、获取所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,,并从中获取所有实现了Ordered接口的BDRPP实现类,后序实现与 2.5相同。
  2.7、调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法;调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法。
3、若beanfactory不为BeanDefinitionRegistry类型
  直接执行postProcessBeanFactory方法
4、上述步骤将入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor(BDRPP)处理完毕,下面该处理所有的BeanFactoryPostProcessor(BFPP).
  4.1、创建存放实现了PriorityOrdered接口的BeanFactoryPostProcessor的集合priorityOrderedPostProcessors、创建存放实现了Ordered接口的BeanFactoryPostProcessor的beanName的集合orderedPostProcessorNames、创建存放普通BeanFactoryPostProcessor的beanName的集合nonOrderedPostProcessorNames。
  4.2、获取所有实现BeanFactoryPostProcessor接口bean的beanName,并记录在集合postProcessorNames中。
  4.3、类型判断,将postProcessorNames中的数据按照实现了PriorityOrdered接口、实现Ordered接口及普通的BeanFactoryPostProcessor的类型分别存储在 4.1中的集合中。
  4.4、创建存储BeanFactoryPostProcessor类型的集合,遍历 4.1 的集合,获取后置处理器的实例并将实例存储进集合中,对集合进行排序并调用invokeBeanFactoryPostProcessors对BeanFactory做后置处理。
5、清除原数据缓存,后置处理器可能已经修改了原始数据。

2、ConfigurationClassPostProcessor源码解析

2.1、ConfigurationClassPostProcessor类图

0

  ConfigurationClassPostProcessor是实现了BeanFactoryRegistryPostProcessor接口。在处理BeanFactory的后置处理器时,解析注解中的beanDefinition信息。

2.2、ConfigurationClassPostProcessor解析注解获取beanDefinition核心流程

0

2.3、ConfigurationClassPostProcessor解析注解获取beanDefinition核心伪代码

  ConfigurationClassPostProcessor#processConfigBeanDefinitions 核心伪代码

 1 // 解析配置的BeanDefinition信息
 2 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
 3    // 获取候选beanDefinition信息集合,用于创建存放BeanDefinitionHolder
 4    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
 5    // 当前registry就是DefaultListableBeanFactory,获取所有已经注册的BeanDefinition的beanName
 6    String[] candidateNames = registry.getBeanDefinitionNames();
 7 
 8    // 遍历所有要处理的beanDefinition的名称,筛选对应的beanDefinition(被注解修饰的)
 9    for (String beanName : candidateNames) {
10       // 获取指定名称的BeanDefinition对象
11       BeanDefinition beanDef = registry.getBeanDefinition(beanName);
12       // 判断beanDefinition是否为一个配置类
13       if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
14          // 添加到对应的集合对象中
15          configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
16       }
17    }
18 
19    // 如果没有发现任何配置类,则直接返回
20    if (configCandidates.isEmpty()) {
21       return;
22    }
23 
24    // 实例化ConfigurationClassParser类,并初始化相关的参数,完成配置类的解析工作
25    ConfigurationClassParser parser = new ConfigurationClassParser(
26          this.metadataReaderFactory, this.problemReporter, this.environment,
27          this.resourceLoader, this.componentScanBeanNameGenerator, registry);
28 
29    // 创建存放相关BeanDefinitionHolder对象的Set集合
30    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
31    // 存放扫描包下的所有bean
32    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
33    do {
34       // 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition
35       parser.parse(candidates);
36       // 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIB
37       parser.validate();
38 
39       // 获取所有的bean,包括扫描的bean对象,@Import导入的bean对象
40       Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
41       // 清除掉已经解析处理过的配置类
42       configClasses.removeAll(alreadyParsed);
43 
44       // 判断读取器是否为空,如果为空的话,就创建完全填充好的ConfigurationClass实例的读取器
45       if (this.reader == null) {
46          this.reader = new ConfigurationClassBeanDefinitionReader(
47                registry, this.sourceExtractor, this.resourceLoader, this.environment,
48                this.importBeanNameGenerator, parser.getImportRegistry());
49       }
50       // 核心方法,将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
51       this.reader.loadBeanDefinitions(configClasses);
52       // 添加到已经处理的集合中
53       alreadyParsed.addAll(configClasses);
54 
55       candidates.clear();
56       // 这里判断的目的是为了知道reader.loadBeanDefinitions(configClasses)这一步有没有向BeanDefinitionMap中添加新的BeanDefinition
57       if (registry.getBeanDefinitionCount() > candidateNames.length) {
58          String[] newCandidateNames = registry.getBeanDefinitionNames();
59          Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
60          Set<String> alreadyParsedClasses = new HashSet<>();
61          for (ConfigurationClass configurationClass : alreadyParsed) {
62             alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
63          }
64          // 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
65          for (String candidateName : newCandidateNames) {
66             if (!oldCandidateNames.contains(candidateName)) {
67                BeanDefinition bd = registry.getBeanDefinition(candidateName);
68                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
69                      !alreadyParsedClasses.contains(bd.getBeanClassName())) {
70                   candidates.add(new BeanDefinitionHolder(bd, candidateName));
71                }
72             }
73          }
74          candidateNames = newCandidateNames;
75       }
76    }
77    while (!candidates.isEmpty());
78 
79 }

1、判断此beanDefinition是否为一个配置类

  ConfigurationClassUtils#checkConfigurationClassCandidate 核心伪代码:

 1 // 判断beanDefinition是否是一个配置类
 2 public static boolean checkConfigurationClassCandidate(
 3       BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
 4 
 5    // 获取bean定义信息中的class类名
 6    String className = beanDef.getBeanClassName();
 7    // 如果className为空,或者bean定义信息中的factoryMethod不等于空,那么直接返回
 8    if (className == null || beanDef.getFactoryMethodName() != null) {
 9       return false;
10    }
11 
12    AnnotationMetadata metadata;
13    // 判断beanDedinition是否实现AnnotatedBeanDefinition接口
14    if (beanDef instanceof AnnotatedBeanDefinition &&
15          className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
16       // 从当前bean的定义信息中获取元数据信息
17       metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
18    }
19    // 判断是否是spring中默认的BeanDefinition
20    else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
21       // 获取当前bean对象的Class对象
22       Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
23       // 如果class实例是下面四种类或接口的子类、父接口等任何一种情况,直接返回
24       if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
25             BeanPostProcessor.class.isAssignableFrom(beanClass) ||
26             AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
27             EventListenerFactory.class.isAssignableFrom(beanClass)) {
28          return false;
29       }
30       // 为给定类创建新的AnnotationMetadata实例
31       metadata = AnnotationMetadata.introspect(beanClass);
32    }
33    // 如果上述两种情况都不符合
34    else {
35          // 获取className的MetadataReader实例
36          MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
37          // 读取底层类的完整注释元数据,包括带注解方法的元数据
38          metadata = metadataReader.getAnnotationMetadata();
39    }
40    
41    // 获取bean定义的元数据被@Configuration注解标注的属性字典值
42    Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
43    
44    // 如果bean被@Configuration注解标注,且属性proxyBeanMethods为false(使用代理模式),则将bean定义记为full
45    if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
46       beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
47    }
48    
49    // 如果bean被@configuration注解标注,且被注解@Component,@ComponentScan、@Import、@ImportResource或者@Bean标记的方法,则将bean定义标记为lite
50    else if (config != null || isConfigurationCandidate(metadata)) {
51       beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
52    }
53    else {
54       return false;
55    }
56    
57    // bean定义是一个标记为full或lite的候选项,如果设置order则设置order属性值
58    Integer order = getOrder(metadata);
59    // 如果值不为空的话,那么直接设置值到具体的beanDefinition
60    if (order != null) {
61       // 设置bean定义的order值
62       beanDef.setAttribute(ORDER_ATTRIBUTE, order);
63    }
64 
65    return true;
66 }

  判断当前BeanDefinition是否是一个配置类,并为BeanDefinition设置属性为lite或者full,此处设置属性值是为了后续进行调用\

  如果Configuration配置proxyBeanMethods代理为true则为full

  如果加了@Bean、@Component、@ComponentScan、@Import、@ImportResource注解,则设置为lite

  如果配置类上被@Order注解标注,则设置BeanDefinition的order属性值

2、解析带有注解的beanDefinition

  ConfigurationClassParser#parse 核心伪代码:

 1 public void parse(Set<BeanDefinitionHolder> configCandidates) {
 2    // 循环遍历configCandidates
 3    for (BeanDefinitionHolder holder : configCandidates) {
 4       // 获取BeanDefinition
 5       BeanDefinition bd = holder.getBeanDefinition();
 6       // 根据BeanDefinition类型的不同,调用parse不同的重载方法,实际上最终都是调用processConfigurationClass()方法
 7          
 8       // 注解类型
 9       if (bd instanceof AnnotatedBeanDefinition) {
10          parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
11       }
12       // 有class对象的
13       else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
14          parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
15       }
16       else {
17          parse(bd.getBeanClassName(), holder.getBeanName());
18       }      
19    }
20 
21    // 执行找到的DeferredImportSelector, 处理@Import注解中导入的bean信息
22    this.deferredImportSelectorHandler.process();
23 }

2.1、解析注解类型

  ConfigurationClassParser#doProcessConfigurationClass 核心伪代码

 1 protected final SourceClass doProcessConfigurationClass(
 2       ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
 3    // 处理@Component
 4    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
 5       // 递归处理内部类,因为内部类也是一个配置类,配置类上有@configuration注解,该注解继承@Component,if判断为true,调用processMemberClasses方法,递归解析配置类中的内部类
 6       processMemberClasses(configClass, sourceClass, filter);
 7    }
 8 
 9    // 如果配置类上加了@PropertySource注解,那么就解析加载properties文件,并将属性添加到spring上下文中
10    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
11          sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
12       if (this.environment instanceof ConfigurableEnvironment) {
13          processPropertySource(propertySource);
14       }
15    }
16 
17    // 处理@ComponentScan或者@ComponentScans注解,并将扫描包下的所有bean转换成填充后的ConfigurationClass
18    // 此处就是将自定义的bean加载到IOC容器,因为扫描到的类可能也添加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析
19    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
20          sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
21    if (!componentScans.isEmpty() &&
22          !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
23       for (AnnotationAttributes componentScan : componentScans) {
24          // 解析@ComponentScan和@ComponentScans配置的扫描的包所包含的类,比如 basePackages = com, 那么在这一步会扫描出这个包及子包下的class,
25          // 然后将其解析成BeanDefinition (BeanDefinition可以理解为等价于BeanDefinitionHolder)
26          Set<BeanDefinitionHolder> scannedBeanDefinitions =
27                this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
28          // 通过上一步扫描包com,有可能扫描出来的bean中可能也添加了ComponentScan或者ComponentScans注解.
29          //所以这里需要循环遍历一次,进行递归(parse),继续解析,直到解析出的类上没有ComponentScan和ComponentScans
30          for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
31             BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
32             if (bdCand == null) {
33                bdCand = holder.getBeanDefinition();
34             }
35             // 判断是否是一个配置类,并设置full或lite属性
36             if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
37                // 通过递归方法进行解析
38                parse(bdCand.getBeanClassName(), holder.getBeanName());
39             }
40          }
41       }
42    }
43 
44    // 处理@Import注解
45    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
46 
47    // 处理@ImportResource注解,导入spring的配置文件
48    AnnotationAttributes importResource =
49          AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
50    if (importResource != null) {
51       String[] resources = importResource.getStringArray("locations");
52       Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
53       for (String resource : resources) {
54          String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
55          configClass.addImportedResource(resolvedResource, readerClass);
56       }
57    }
58 
59    // 处理加了@Bean注解的方法,将@Bean方法转化为BeanMethod对象,保存再集合中
60    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
61    for (MethodMetadata methodMetadata : beanMethods) {
62       configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
63    }
64 
65    // 处理接口的默认方法实现,从jdk8开始,接口中的方法可以有自己的默认实现,因此如果这个接口的方法加了@Bean注解,也需要被解析
66    processInterfaces(configClass, sourceClass);
67 
68    // 解析父类,如果被解析的配置类继承了某个类,那么配置类的父类也会被进行解析
69    if (sourceClass.getMetadata().hasSuperClass()) {
70       String superclass = sourceClass.getMetadata().getSuperClassName();
71       if (superclass != null && !superclass.startsWith("java") &&
72             !this.knownSuperclasses.containsKey(superclass)) {
73          this.knownSuperclasses.put(superclass, configClass);
74          // Superclass found, return its annotation metadata and recurse
75          return sourceClass.getSuperClass();
76       }
77    }
78 
79    return null;
80 }

  2.2、解析Class对象类型

  2.3、解析默认类型

  2.4、解析Import

3、将注解的beanDefinition加入IOC容器

3、总结

  invokeBeanFactoryPostProcessors方法主要是调用BeanFactoryPostProcessor后置处理器,可对容器中的BeanDefinition做修改(添加beanDefinition)。对于BeanFactoryRegistryPostProcessor类型的后置处理器,调用postProcessBeanDefinitionRegistry方法;对于BeanFactoryPostProcessor类型的后置处理器,调用postProcessBeanFactory方法。

posted @ 2022-12-23 20:09  无虑的小猪  阅读(158)  评论(0编辑  收藏  举报