本节主要介绍SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext方法,该方法是 Spring 提供的一个工具方法,用于在非 Spring 管理的对象中手动触发依赖注入。它的实现原理与 Spring 的 IoC 容器机制 和 上下文查找机制 有关。
一、方法签名
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
- this:表示当前对象实例。
- 作用:将 Spring 容器中的 Bean 注入到该对象的 @Autowired 字段或方法中。
二、核心原理概述
这个方法的本质是:
从当前线程上下文中获取 Spring 容器(ApplicationContext),然后对该对象进行自动装配(autowire)。
实现步骤如下:
- 从当前线程中查找 Spring 上下文(ApplicationContext)
- 使用 Spring 的 AutowireCapableBeanFactory 对目标对象进行依赖注入
- 将容器中的 Bean 按照 @Autowired、@Value 等注解注入到目标对象中
三、源码解析(简化版)
SpringBeanAutowiringSupport 类的关键方法:
processInjectionBasedOnCurrentContext(Object target)
public static void processInjectionBasedOnCurrentContext(Object target) {
// 获取当前线程绑定的 WebApplicationContext
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(
RequestContextHolder.currentRequestAttributes().getRequest().getServletContext()
);
// 使用 Spring 的 autowire 功能对 target 进行注入
context.getAutowireCapableBeanFactory().autowireBean(target);
}
这段代码的核心逻辑是:
- 通过 RequestContextHolder.currentRequestAttributes() 获取当前请求的 ServletContext
- 通过 WebApplicationContextUtils.getRequiredWebApplicationContext(...) 获取 Spring 容器
- 调用 AutowireCapableBeanFactory.autowireBean(target) 对目标对象进行自动装配
四、关键组件详解
1. WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext servletContext)
- 从 ServletContext 中获取 Spring 的上下文 WebApplicationContext
- 如果找不到会抛出异常
2. RequestContextHolder.currentRequestAttributes()
- 获取当前线程绑定的请求上下文(只能在 Web 请求线程中调用)
- 适用于有 HTTP 请求上下文的场景(如 Controller、Filter、WebSocket)
3. AutowireCapableBeanFactory.autowireBean(Object existingBean)
- Spring 提供的接口,用于对一个已存在的对象进行自动装配
- 支持字段注入、构造函数注入、setter 方法注入等
- 本质上是模拟 Spring 创建 Bean 的过程,但跳过了创建 Bean 的步骤,只做属性填充和初始化
五、注意事项
注意点 | 说明 |
必须处于 Spring Web 上下文中 | 只能在 Web 应用中使用,且必须能访问到 WebApplicationContext |
非 Web 场景无法使用 | 如普通 Java 应用、定时任务、多线程中需改用其他方式(如静态上下文工具类) |
性能开销 | 涉及反射、上下文查找、依赖注入等操作,频繁调用会影响性能 |
推荐替代方案 | 尽量让类成为 Spring Bean(使用 @Component, @Service 等),避免手动注入 |
六、推荐替代方案(更优雅)
方案 1:使用静态上下文工具类
@Component
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
使用时:
MyService myService = SpringContext.getBean(MyService.class);
方案 2:让类成为 Spring Bean
@Component
public class MyCustomClass {
@Autowired
private MyService myService;
// ...
}
七、小结
特性 | 描述 |
作用 | 手动对非 Spring Bean 的对象进行依赖注入 |
实现原理 | 从当前线程获取 Spring 上下文,使用 AutowireCapableBeanFactory 注入 |
适用场景 | WebSocket、Filter、Servlet、new 出来的类等 |
不适用场景 | 非 Web 环境、无 Spring 上下文的线程 |
推荐替代 | 使用 @Component 注册为 Bean 或使用静态上下文工具类 |