Spring源码解析CommonAnnotationBeanPostProcessor

2022-11-13 18:11:56 spring 源码 解析

概述

基于 spring Framework v5.2.6.RELEASE

前面的几篇文章,通过源码分析了 AnnotationConfigApplicationContext 初始化时注册的两个关键的后处理器 ConfigurationClassPostProcessor 和 AutowiredAnnotationBeanPostProcessor 的作用和工作原理,本文接着介绍第三个关键的后处理器 CommonAnnotationBeanPostProcessor。

以下是 Spring 上下文初始化过程中,CommonAnnotationBeanPostProcessor 被注册的代码片段。这段代码在 AnnotationConfigUtils 类的registerAnnotationConfigProcessors方法中。

registerAnnotationConfigProcessors

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

从代码的注释中可以看到,这个后处理器的作用,是为了适配 JSR-250 的特性,关于 JSR-250 是什么,会在下文中介绍。

除此之外,除了判断当前的容器是否已经注册了这个后处理器外,还有一个判断条件是jsr250Present,这个变量的初始化可以在 AnnotationConfigUtils 类中的静态代码块里找到:

jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader);

其实就是看能不能加载到javax.annotation.Resource类型,如果能,则jsr250Present的值就是true。也就是说,如果能加载到javax.annotation.Resource类型,说明当前 Spring 运行的环境是支持 JSR-250 特性的,只有在这种条件下,Spring 才需要注册 CommonAnnotationBeanPostProcessor 后处理器。

说了这么多,我们有必要先了解一下 JSR-250 是什么。

JSR 和 JSR-250

JSR 是 Java Specification Requests 的缩写,意思是「Java 规范提案」,是 Java 平台重要的技术标准。JSR 由开放组织 JCP(Java CommUnity Process)维护,任何组织成员都可以提出 JSR 提案,以向 Java 平台提供新的规范和技术,经过公开审查和 JCP 执行委员会的投票,JSR 会最终成为正式的标准。

JSR-250 的全称是 Common Annotations for the JavaTM PlatfORM,也就是 Java 平台的公共注解。这也是本文要介绍的后处理器名字叫 CommonAnnotationBeanPostProcessor 的原因。

参考链接:The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 250

JSR-250 注解可以在javax.annotation包下找到。

我们打开其中的一个注解的源码,比如 Resource 的源码。

可以看到,注释中标记了支持该注解的 jdk 起始版本之外,还注明了起始的 Common Annotations 版本。

了解这些之后,我们回到 Spring 的源码,开始分析 CommonAnnotationBeanPostProcessor 后处理器。

CommonAnnotationBeanPostProcessor 分析

根据惯例,还是先从它的类继承关系下手。

可以看到,它是一个 BeanPostProcessor 的实现类,实现了4个 Bean 后处理器接口,并继承了 InitDestroyAnnotationBeanPostProcessor 类。

我们再看一下它实现的这些接口中,定义了哪些后处理方法。

要分析 Spring 是如何通过 CommonAnnotationBeanPostProcessor 来支持 JSR-250 特性的,就需要从这些方法下手。我们可以从 CommonAnnotationBeanPostProcessor 和它的父类 InitDestroyAnnotationBeanPostProcessor 的源码中,查找它们实现了哪些处理方法。总结如下:

CommonAnnotationBeanPostProcessor 主要在postProceSSMergedBeanDefinitionpostProcessProperties方法中增加了处理逻辑。InitDestroyAnnotationBeanPostProcessor 则主要在postProcessBeforeInitializationpostProcessBeforeDestruction方法中增加了处理逻辑。

最后,再简单地介绍一下这几个后处理方法被调用的时机:

  • postProcessMergedBeanDefinition 在通过doCreateBean使用反射机制创建 Bean 实例之后调用。
  • postProcessProperties 在装配 Bean 实例的属性前对属性进行处理。
  • postProcessBeforeInitialization 在 Bean 实例的初始化方法执行前被调用。
  • postProcessBeforeDestruction 在 Bean 实例的销毁方法执行前被调用。

Spring 主要对@Resource@PostConstruct@PreDestroy三个 JSR-250 注解提供了支持,其实根据三个注解的名称,和以上介绍的几个后处理方法被调用的时机,就能知道它们的对应关系。具体的工作原理,我们放到之后的文章中介绍。

总结

本文介绍了 CommonAnnotationBeanPostProcessor 后处理器的作用、它主要实现的后处理方法,还顺便介绍了 JSR 和 JSR-250 是什么。之后的文章,将深入分析这几个后处理器方法分别做了哪些工作,更多关于Spring CommonAnnotationBeanPostProcessor的资料请关注其它相关文章!

相关文章