Spring中手动获取Bean仅适用于特殊场景,需确保ApplicationContext已初始化,推荐按类型调用getBean(Class);应优先使用依赖注入而非手动获取以降低耦合。

在 Spring 中,可以通过 ApplicationContext 手动获取 Bean,但需注意:这不是推荐的常规用法(违背依赖注入原则),仅适用于特殊场景,如工具类、动态加载、或非 Spring 管理的对象中需要临时访问 Bean。
确保 ApplicationContext 已正确初始化
手动获取 Bean 前,必须已有可用的 ApplicationContext 实例。常见方式包括:
- 在 Spring Boot 应用中,可通过实现
ApplicationContextAware接口保存上下文 - 在 Web 环境中,可使用
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext) - 若在启动类中(如
@SpringBootApplication类),可通过SpringApplication.run(...)返回的ApplicationContext保存引用
通过 getBean() 方法获取 Bean
ApplicationContext 提供多个重载的 getBean() 方法,常用方式有:
-
按类型获取(推荐):
context.getBean(YourService.class)—— 类型唯一时最安全,避免硬编码字符串 -
按名称 + 类型获取:
context.getBean("userService", UserService.class)—— 名称不唯一但类型唯一时更精准 -
仅按名称获取(不推荐):
context.getBean("userService")—— 返回Object,需强制转型,易出ClassCastException
注意:若 Bean 未被 Spring 管理(如 new 出来的对象)、或类型/名称不匹配,会抛出 NoSuchBeanDefinitionException。
立即学习“Java免费学习笔记(深入)”;
在非托管类中安全持有 ApplicationContext
避免静态变量滥用,推荐使用线程安全且可测试的方式保存上下文。例如:
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return context.getBean(name, clazz);
}
}
使用时:MyService service = SpringContextUtil.getBean(MyService.class);
替代方案:优先考虑依赖注入
手动获取 Bean 容易导致耦合、难以单元测试。更优做法是:
- 将所需 Bean 作为构造函数参数或
@Autowired字段注入 - 对工厂类或策略选择器,使用
ObjectProvider<T>或ListableBeanFactory动态获取 - 在配置类中通过
@Bean方法组合依赖,而非运行时查找
只有当 Bean 生命周期不受 Spring 控制(如 Servlet、Filter、第三方回调)时,才应谨慎使用手动获取。


















