深入理解 Spring Bean 后处理器@Autowired 等注解的本质(示例demo)

 更新时间:2025年10月09日 11:05:52   作者:冼紫菜  
在日常开发中,我们几乎每天都会用到 @Autowired、@Value、@Resource、@PostConstruct 等注解,今天我们通过一个非常简洁的 Demo,一步步揭开 Spring Bean 后处理器的秘密,感兴趣的朋友一起看看吧

在日常开发中,我们几乎每天都会用到 @Autowired@Value@Resource@PostConstruct 等注解。
但你是否想过,这些“神奇”的注入和生命周期回调机制,是谁在幕后完成的?
今天我们通过一个非常简洁的 Demo,一步步揭开 Spring Bean 后处理器的秘密。

一、代码示例

package com.itheima.a04;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;
/*
 * Bean 后处理器的作用演示
 */
public class A04 {
    public static void main(String[] args) {
        // 1️⃣ 创建一个“干净”的容器(没有任何自动注册的组件)
        GenericApplicationContext context = new GenericApplicationContext();
        // 2️⃣ 手动注册一些普通 Bean
        context.registerBean("bean1", Bean1.class);
        context.registerBean("bean2", Bean2.class);
        context.registerBean("bean3", Bean3.class);
        context.registerBean("bean4", Bean4.class);
        // 3️⃣ 配置容器的自动注入解析策略(支持 @Value)
        context.getDefaultListableBeanFactory()
                .setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        // 4️⃣ 手动注册各种 Bean 后处理器
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 负责解析 @Autowired 和 @Value
        context.registerBean(CommonAnnotationBeanPostProcessor.class);   // 负责解析 @Resource、@PostConstruct、@PreDestroy
        ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory()); // 负责解析 @ConfigurationProperties
        // 5️⃣ 初始化容器(执行 BeanFactory 后处理器、添加 BeanPostProcessor、初始化所有单例 Bean)
        context.refresh();
        System.out.println(context.getBean(Bean1.class));
        // 6️⃣ 关闭容器,触发销毁回调
        context.close();
        /*
            学到什么?
            ✅ 1. @Autowired、@Value、@Resource、@PostConstruct 等注解的功能,
                   都是由 Bean 后处理器在 Bean 生命周期阶段完成的。
            ✅ 2. Bean 后处理器本身也是一种“插件机制”,可以扩展 Spring 的核心行为。
         */
    }
}

二、Demo 核心逻辑解析

这段代码其实干了三件事:

1️⃣ 创建一个干净的容器

GenericApplicationContext 是 Spring 提供的一个空白容器实现
它不像 AnnotationConfigApplicationContext 那样自动注册注解处理器、扫描包路径或加载配置类。
换句话说,它是“白纸一张”,这就让我们可以手动控制 Spring 容器内部机制

GenericApplicationContext context = new GenericApplicationContext();

2️⃣ 手动注册 Bean 与处理器

正常情况下,Spring 会自动帮你注册 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 等组件。
但这里我们手动注册它们,以便更清楚地看到它们的作用:

注册组件功能说明
AutowiredAnnotationBeanPostProcessor解析 @Autowired@Value
CommonAnnotationBeanPostProcessor解析 @Resource@PostConstruct@PreDestroy
ConfigurationPropertiesBindingPostProcessor解析 @ConfigurationProperties
ContextAnnotationAutowireCandidateResolver支持 @Value("${}") 等表达式解析

这几行代码告诉我们:
👉 Spring 并没有“魔法”地识别这些注解,而是通过后处理器扩展点去实现的。

3️⃣ 初始化容器与销毁

context.refresh() 会触发以下流程:

  1. 执行 BeanFactoryPostProcessor(工厂级别的增强)
  2. 注册所有 BeanPostProcessor
  3. 实例化所有单例 Bean
  4. 在创建 Bean 的过程中,各个后处理器开始发挥作用,完成依赖注入与生命周期方法调用。

随后,context.close() 会触发销毁阶段,执行:

  • @PreDestroy 注解的方法
  • DisposableBean 接口方法
  • 自定义销毁回调

三、结论:后处理器是 Spring 的灵魂

这个 Demo 的意义非常深刻,它揭示了一个关键真相:

Spring 框架中几乎所有“魔法”都是通过 Bean 后处理器(BeanPostProcessor)实现的。

下面是一个简单的关系图,帮助理解:

Spring Bean 生命周期(精简版)
      实例化前 → [InstantiationAwareBeanPostProcessor]
      构造方法执行(实例化)
      属性注入 → [AutowiredAnnotationBeanPostProcessor]
      初始化前 → [CommonAnnotationBeanPostProcessor 处理 @PostConstruct]
      初始化后 → [AOP、代理增强等]
      销毁前 → [CommonAnnotationBeanPostProcessor 处理 @PreDestroy]

四、总结

关键点说明
后处理器是 Spring 可扩展机制的核心所有注解的功能其实都是“插件化”的
@Autowired 等注解不是语法糖,而是由后处理器解释执行的运行期反射完成依赖注入
容器生命周期由 refresh() 驱动包括 Bean 定义加载、处理器注册、Bean 实例化、初始化等步骤
你也可以编写自己的 BeanPostProcessor比如自定义注解、监控 Bean 加载时间、实现 AOP 增强等

五、总结一句话

Spring 的强大,不在于注解本身,而在于它提供了可以“挂接任意逻辑”的生命周期扩展机制。

到此这篇关于深入理解 Spring Bean 后处理器@Autowired 等注解的本质的文章就介绍到这了,更多相关Spring Bean @Autowired 注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot整合freemarker的踩坑及解决

    springboot整合freemarker的踩坑及解决

    这篇文章主要介绍了springboot整合freemarker的踩坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • dom4j操作xml的demo(分享)

    dom4j操作xml的demo(分享)

    下面小编就为大家带来一篇dom4j操作xml的demo(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Java中Integer.parseInt和Integer.valueOf区别小结

    Java中Integer.parseInt和Integer.valueOf区别小结

    在Java中,Integer.parseInt()和Integer.valueOf()都可以将字符串转换为整数类型,那么他们有哪些区别呢,本文就来详细的介绍一下
    2023-09-09
  • SpringMVC JSON数据交互实现过程解析

    SpringMVC JSON数据交互实现过程解析

    这篇文章主要介绍了SpringMVC JSON数据交互实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java Web关键字填空示例详解

    Java Web关键字填空示例详解

    最近在工作中使用了java web,发现有些难度,下面这篇文章主要给大家介绍了关于Java Web关键字填空的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • Java并发工具之CountDownLatch使用详解

    Java并发工具之CountDownLatch使用详解

    这篇文章主要介绍了Java并发工具之CountDownLatch使用详解,通过使用 CountDownLatch可以使当前线程阻塞,等待其他线程完成给定任务,可以类比旅游团导游要等待所有的游客到齐后才能去下一个景点,需要的朋友可以参考下
    2023-12-12
  • java8 forEach结合Lambda表达式遍历 List操作

    java8 forEach结合Lambda表达式遍历 List操作

    这篇文章主要介绍了java8 forEach结合Lambda表达式遍历 List操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java中ResponseBodyEmitter的实现

    Java中ResponseBodyEmitter的实现

    这篇文章主要介绍了Java中ResponseBodyEmitter的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 一篇文章带你理解Java Spring三级缓存和循环依赖

    一篇文章带你理解Java Spring三级缓存和循环依赖

    这篇文章主要介绍了浅谈Spring 解决循环依赖必须要三级缓存吗,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-09-09
  • jQuery 动画效果代码分享

    jQuery 动画效果代码分享

    本文给大家分享一段关于jquery实现的动画效果,代码简单易懂,非常不错,感兴趣的朋友参考下
    2016-11-11

最新评论