直接实现 applicationcontextaware 接口是最常用、最稳妥的获取全局 applicationcontext 的方式,通过@component注解让spring管理工具类,静态保存上下文并提供getbean方法,适用于非spring管理对象等场景。

直接实现 ApplicationContextAware 接口是最常用、最稳妥的获取全局 ApplicationContext 的方式。它由 Spring 框架自动回调,确保上下文已完全初始化,适合在任意被 Spring 管理的 Bean 中安全使用。
核心步骤:写一个带@Component的工具类
必须让 Spring 容器管理这个类,否则 setApplicationContext 不会被调用。推荐做法是:
- 添加
@Component注解(或@Service/@Configuration等) - 定义一个 静态变量 存储上下文,供后续任意位置调用
- 重写
setApplicationContext方法,把传入的上下文赋值给静态变量
典型代码示例
以下是一个简洁可靠的实现:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <t> T getBean(Class<t> clazz) {
return context.getBean(clazz);
}
public static Object getBean(String name) {
return context.getBean(name);
}
}</t></t>
之后 anywhere 都能用:UserService userService = SpringContextUtil.getBean(UserService.class);Object bean = SpringContextUtil.getBean("userServiceImpl");
注意事项:避免空指针和线程安全问题
这个方式看似简单,但有两个关键细节容易出错:
- 不能在静态块或静态字段初始化时调用 getBean —— 因为 setApplicationContext 还没执行,context 仍是 null
- 无需手动加 synchronized —— Spring 容器启动时只调用一次 setApplicationContext,且发生在单线程初始化阶段,静态变量赋值是线程安全的
- 如果项目启用了多个上下文(如 Web + Root),注意该实现默认拿到的是当前活跃的主上下文(通常是 AnnotationConfigServletWebServerApplicationContext)
为什么比 @Autowired 更通用?
当你要在工具类、静态方法、甚至非 Spring 管理的对象(比如某些 SDK 回调)中获取 Bean 时,@Autowired 失效(因为那些对象不是 Spring Bean)。而 ApplicationContextAware 方式生成的工具类是 Spring 管理的,它“记住”了容器,就能跨场景提供服务。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










