spring源码(六)注册Bean后置处理

前言

源码版本:

1
2
3
4
5
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>

上一篇看了spring如何使用ConfigurationClassPostProcessor来解析配置文件的。本篇主要看AbstractApplicationContext的registerBeanPostProcessors方法,

1
2
                // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

从方法上面的注释可以知道,这个方法是注册Bean后置处理的。

正文

下面直接定位至PostProcessorRegistrationDelegate的registerBeanPostProcessors方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    public static void registerBeanPostProcessors(
         ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 获取工厂中类型为BeanPostProcessor的beanName的集合
      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

      // Register BeanPostProcessorChecker that logs an info message when
      // a bean is created during BeanPostProcessor instantiation, i.e. when
      // a bean is not eligible for getting processed by all BeanPostProcessors.
      int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
      beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

      // Separate between BeanPostProcessors that implement PriorityOrdered,
      // Ordered, and the rest.
      // 分离实现了PriorityOrdered,Ordered的BeanPostProcessors和剩余的,其实就是将BeanPostProcessors分类
      List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
      List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
      List<String> orderedPostProcessorNames = new ArrayList<>();
      List<String> nonOrderedPostProcessorNames = new ArrayList<>();
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 分离实现PriorityOrdered的
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) { // 再分离实现MergedBeanDefinitionPostProcessor的
               internalPostProcessors.add(pp);
            }
         }
         else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //分离实现Ordered的
            orderedPostProcessorNames.add(ppName);
         }
         else { // 其余的,剩下的
            nonOrderedPostProcessorNames.add(ppName);
         }
      }

      // First, register the BeanPostProcessors that implement PriorityOrdered.
      // 首先,注册实现了PriorityOrdered的BeanPostProcessors
      sortPostProcessors(priorityOrderedPostProcessors, beanFactory);// 排序
      registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 注册

      // Next, register the BeanPostProcessors that implement Ordered.
      // 然后,注册实现了Ordered的BeanPostProcessors
      List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
      for (String ppName : orderedPostProcessorNames) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         orderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      sortPostProcessors(orderedPostProcessors, beanFactory); // 排序
      registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 注册

      // Now, register all regular BeanPostProcessors.
      // 注册所有的常规的BeanPostProcessors
      List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
      for (String ppName : nonOrderedPostProcessorNames) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         nonOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      // 注册
      registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); 

      // Finally, re-register all internal BeanPostProcessors.
      // 最后,重新注册所有常规的BeanPostProcessors(就是实现MergedBeanDefinitionPostProcessor的BeanPostProcessors)
      sortPostProcessors(internalPostProcessors, beanFactory); // 排序
      registerBeanPostProcessors(beanFactory, internalPostProcessors); // 注册

      // Re-register post-processor for detecting inner beans as ApplicationListeners,
      // moving it to the end of the processor chain (for picking up proxies etc).
      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));// 添加一个ApplicationListenerDetector
   }
   

注释都写到代码里面了。这个方法也不复杂,总体来说就一个功能:就是注册BeanPostProcessors。下面是整个方法的流程图:

image.png

MergedBeanDefinitionPostProcessor

在上面的方法中,多次出现了MergedBeanDefinitionPostProcessor,下面来看看这个接口是干啥的;先来看看这个类的注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

    /**
     * Post-processor callback interface for <i>merged</i> bean definitions at runtime.
     * {@link BeanPostProcessor} implementations may implement this sub-interface in order
     * to post-process the merged bean definition (a processed copy of the original bean
     * definition) that the Spring {@code BeanFactory} uses to create a bean instance.
     * 后置处理的回调接口,为了在运行时合并bean信息。
     * BeanPostProcessor的实现类可以实现这个子接口,以便Spring BeanFactory在创建bean实例时需要合并bean信息(一个对原始bean信息处理过的副本)
     * 
     * <p>The {@link #postProcessMergedBeanDefinition} method may for example introspect
     * the bean definition in order to prepare some cached metadata before post-processing
     * actual instances of a bean. It is also allowed to modify the bean definition but
     * <i>only</i> for definition properties which are actually intended for concurrent
     * modification. Essentially, this only applies to operations defined on the
     * {@link RootBeanDefinition} itself but not to the properties of its base classes.
     * postProcessMergedBeanDefinition这个方法可以 例如:为了在实际实例化bean的后置处理之前准备一些缓存的元数据去自定义bean信息。
     * 它还允许修改bean定义,但只允许对实际用于并发修改的定义属性进行修改。
     * 本质上,这只适用于在RootBeanDefinition本身上定义的操作,而不适用于其基类的属性
     * 
     */
     

总结起来就是:可以修改bean的一些属性信息。

其实在这个地方的registerBeanPostProcessors方法中(spring-context 5.2.8中),放到internalPostProcessors中的MergedBeanDefinitionPostProcessor接口的实现类有两个, 一个是AutowiredAnnotationBeanPostProcessor,一个是CommonAnnotationBeanPostProcessor,这里只写了AutowiredAnnotationBeanPostProcessor, 其实CommonAnnotationBeanPostProcessor主要就是处理下面这几个的,感兴趣的可以去看看他的具体实现。

1
2
3
4
5
6
7
8
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import javax.annotation.Resource;
    import javax.ejb.EJB;
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    import javax.xml.ws.WebServiceClient;
    import javax.xml.ws.WebServiceRef;

AutowiredAnnotationBeanPostProcessor

这个类是MergedBeanDefinitionPostProcessor的实现类,从命名上面就可以看出这个类做自动装配方面的事情的。

构造方法
1
2
3
4
5
6
7
8
9
10
11
12
    public AutowiredAnnotationBeanPostProcessor() {
      this.autowiredAnnotationTypes.add(Autowired.class);
      this.autowiredAnnotationTypes.add(Value.class);
      try {
         this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
               ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
         logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
      }
      catch (ClassNotFoundException ex) {
         // JSR-330 API not available - simply skip.
      }
   }

构造方法就是向autowiredAnnotationTypes中放入AutowiredValueInject

postProcessMergedBeanDefinition方法
1
2
3
4
5
6
7
    @Override
   public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
       // 查询自动装配的元数据
      InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
      // 检查配置方法
      metadata.checkConfigMembers(beanDefinition);
   }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
      // Fall back to class name as cache key, for backwards compatibility with custom callers.
      String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
      // Quick check on the concurrent map first, with minimal locking.
      InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
      if (InjectionMetadata.needsRefresh(metadata, clazz)) {
         synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
               if (metadata != null) {
                  metadata.clear(pvs);
               }
               metadata = buildAutowiringMetadata(clazz);
               this.injectionMetadataCache.put(cacheKey, metadata);
            }
         }
      }
      return metadata;
   }

这个方法主要流程就是:

  1. 判断缓存
  2. 加锁
  3. 构建数据
  4. 存缓存

其中用到了双重检验锁,这个方法最重要的就是buildAutowiringMetadata这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
      if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
         return InjectionMetadata.EMPTY;
      }

      List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
      Class<?> targetClass = clazz;

      do {
          // 构建currElements,用来存储符合条件的数据
         final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            // 遍历当前类的参数
         ReflectionUtils.doWithLocalFields(targetClass, field -> {
             //  查找符合条件的参数(就是被构造函数中的三个注解修饰的)
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
               if (Modifier.isStatic(field.getModifiers())) {
                  if (logger.isInfoEnabled()) {
                     logger.info("Autowired annotation is not supported on static fields: " + field);
                  }
                  return;
               }
               // 获取required参数
               boolean required = determineRequiredStatus(ann);
               // 符合条件则加入
               currElements.add(new AutowiredFieldElement(field, required));
            }
         });
            // 遍历当前类的所有方法
         ReflectionUtils.doWithLocalMethods(targetClass, method -> {
             // 查找符合条件的方法(同上)
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
               return;
            }
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
               if (Modifier.isStatic(method.getModifiers())) {
                  if (logger.isInfoEnabled()) {
                     logger.info("Autowired annotation is not supported on static methods: " + method);
                  }
                  return;
               }
               if (method.getParameterCount() == 0) {
                  if (logger.isInfoEnabled()) {
                     logger.info("Autowired annotation should only be used on methods with parameters: " +
                           method);
                  }
               }
               // 获取required参数
               boolean required = determineRequiredStatus(ann);
               PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
               // 添加到currElements
               currElements.add(new AutowiredMethodElement(method, required, pd));
            }
         });

         elements.addAll(0, currElements);
         targetClass = targetClass.getSuperclass();
      }
      while (targetClass != null && targetClass != Object.class); // 向上遍历,直到父类为Object为止。

      return InjectionMetadata.forElements(elements, clazz); // 返回
   }
   

这个方法主要就是以下几点:

  1. 不断向上遍历,直到父类为Object为止。
  2. 遍历类的参数和方法,找到符合条件(被@Autowired@Value@Inject修饰)的参数和方法,最后放入集合中
  3. 将集合封装后返回
1
2
3
4
5
6
7
8
9
10
    private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
      MergedAnnotations annotations = MergedAnnotations.from(ao);
      for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
         MergedAnnotation<?> annotation = annotations.get(type);
         if (annotation.isPresent()) {
            return annotation;
         }
      }
      return null;
   }

这个方法就是在遍历autowiredAnnotationTypes,判断参数或方法是否被autowiredAnnotationTypes里面的注解修饰,有就直接返回了。

现在,通过findAutowiringMetadata方法,已经找到了被相应注解修饰的参数和方法,接下来就是执行checkConfigMembers方法了。 这个方法在org.springframework.beans.factory.annotation.InjectionMetadata类中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public void checkConfigMembers(RootBeanDefinition beanDefinition) {
      Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
      for (InjectedElement element : this.injectedElements) {
         Member member = element.getMember();
         if (!beanDefinition.isExternallyManagedConfigMember(member)) {
            beanDefinition.registerExternallyManagedConfigMember(member);
            checkedElements.add(element);
            if (logger.isTraceEnabled()) {
               logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
            }
         }
      }
      this.checkedElements = checkedElements;
   }

这个方法就是遍历从findAutowiringMetadata方法拿到的数据,返回封装这些数据,最后放入到RootBeanDefinition中,也就是bean定义信息中。

最后

至此,spring中的后置处理就已经注册完成了,至于什么时候被调用,就要继续往后面看了。

坚持原创技术分享,您的支持将鼓励我继续创作!