Spring 源码解析CommonAnnotationBeanPostProcessor

 更新时间:2022年10月13日 16:02:42   作者:Pseudocode  
这篇文章主要为大家介绍了Spring 源码解析CommonAnnotationBeanPostProcessor示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

概述

基于 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的资料请关注脚本之家其它相关文章!

相关文章

  • 详解springboot中mybatis注解形式

    详解springboot中mybatis注解形式

    在本文中小编给大家分享了关于springboot中mybatis注解形式的介绍,有兴趣的可以跟着学习下。
    2018-10-10
  • Java 常用类解析:java异常机制,异常栈,异常处理方式,异常链,异常丢失详解

    Java 常用类解析:java异常机制,异常栈,异常处理方式,异常链,异常丢失详解

    这篇文章主要介绍了Java 常用类解析:java异常机制,异常栈,异常处理方式,异常链,异常丢失详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • 浅谈SpringMVC对RESTfull的支持

    浅谈SpringMVC对RESTfull的支持

    这篇文章主要介绍了浅谈SpringMVC对RESTfull的支持,分享了相关配置代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 详解Java 线程中断

    详解Java 线程中断

    这篇文章主要介绍了Java 线程中断的相关资料,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2021-02-02
  • Java基础之FastJson详解

    Java基础之FastJson详解

    今天给大家复习Java基础FastJson,文中有非常详细的代码示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • vue+springboot读取git的markdown文件并展示功能

    vue+springboot读取git的markdown文件并展示功能

    Markdown-it 是一个用于解析和渲染 Markdown 标记语言的 JavaScript 库,使用 Markdown-it,你可以将 Markdown 文本解析为 HTML 输出,并且可以根据需要添加功能、扩展语法或修改解析行为,本文介绍vue+springboot读取git的markdown文件并展示,感兴趣的朋友一起看看吧
    2024-01-01
  • java中如何获取线程名称

    java中如何获取线程名称

    这篇文章主要介绍了java中如何获取线程名称问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 基于Class.forName()用法及说明

    基于Class.forName()用法及说明

    这篇文章主要介绍了基于Class.forName()用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 关于@Scheduled注解的任务为什么不执行的问题

    关于@Scheduled注解的任务为什么不执行的问题

    这篇文章主要介绍了关于@Scheduled注解的任务为什么不执行的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • 使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08

最新评论