当前位置: 首页 > news >正文

Sping中获取bean的方式总结-笔记

1. 获取spring管理bean的方式

1.1 通过@Autowired依赖注入

通过字段、构造函数或 setter 方法自动注入Bean,是Spring最常用的方式。

@Service
public class MyBeanConsumer {// 字段注入@Autowiredprivate MyService myService;
}@Service
public class MyBeanConsumer {private MyService myService;// 构造函数注入@Autowiredpublic MyBeanConsumer(MyService myService) {this.myService = myService;}
}@Service
public class MyBeanConsumer {private MyService myService;// Setter注入@Autowiredpublic void setMyService(MyService myService) {this.myService = myService;}
}

1.2. 通过@Resource依赖注入

使用Java EE标准的@Resource注解,按名称注入(默认按字段名匹配Bean名称)。

@Service
public class MyBeanConsumer {// 按字段名"myService"匹配Bean名称@Resourceprivate MyService myService;// 显式指定Bean名称(如Bean名为"anotherService")@Resource(name = "anotherService")private MyService anotherService;
}

1.3 通过ApplicationContextgetBean()方法

这是直接通过ApplicationContext上下文获取Bean的方式,适用于需要动态或按名称获取Bean的场景。

// 在某个组件或测试类中注入ApplicationContext
@Service
public class MyBeanConsumer {@Autowiredprivate ApplicationContext context;public void doSomething() {// 按类型获取Bean(若存在多个同类型Bean需指定名称)MyService myService = context.getBean(MyService.class);// 按名称+class获取Bean(需指定Bean名称)MyService namedService = context.getBean("myServiceBean", MyService.class);// 按名称获取MyService myService = (MyService)context.getBean("myServiceBean");}
}

1.4. 通过ApplicationContextAware接口

通过实现ApplicationContextAware接口,保存ApplicationContext的引用,从而全局获取Bean。

@Component //需要使用@Component,让spring能够扫描到该工具类
public class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {//Spring项目启动过程中,会执行ApplicationContextAware接口实现类的setApplicationContext方法,自动注入applicationContextcontext = applicationContext;}// 静态方法供其他类调用// 通过class获取Beanpublic static <T> T getBean(Class<T> beanClass) {return context.getBean(beanClass);}//通过beanName+Clazz返回指定的Beanpublic static <T> T getBean(String beanName, Class<T> clazz) {return getApplicationContext().getBean(beanName, clazz);}//通过beanName获取 Beanpublic static Object getBean(String beanName){return context.getBean(beanName);}
}// 在其他类中使用
public class AnotherClass {public void someMethod() {MyService service = SpringContextUtil.getBean(MyService.class);}
}

1.5. 通过BeanFactorygetBean()方法

BeanFactory是Spring的核心接口,ApplicationContext继承自它,功能类似。

@Service
public class MyBeanConsumer {@Autowiredprivate BeanFactory beanFactory;public void doSomething() {// 按类型获取Bean(若存在多个同类型Bean需指定名称)MyService myService = beanFactory.getBean(MyService.class);// 按名称+class获取Bean(需指定Bean名称)MyService namedService = beanFactory.getBean("myServiceBean", MyService.class);// 按名称获取MyService myService = (MyService)beanFactory.getBean("myServiceBean");}
}

2. 各种获取bean方式的对比

2.1 各方式的对比分析

方式依赖注入方式适用场景侵入性灵活性可测试性性能
@Autowired自动注入(类型匹配)常规 Bean 注入,类型唯一时高(依赖注入)高(启动时完成注入)
@Resource自动注入(名称匹配)需明确指定 Bean 名称时
ApplicationContext.getBean()手动获取动态获取 Bean(如条件判断)中(需持有上下文)高(动态选择)低(需模拟上下文)中(需查找 Bean)
ApplicationContextAware手动获取需全局访问 ApplicationContext高(全局耦合)
BeanFactory.getBean()手动获取底层 API 场景

2.2 关键对比说明

1. 自动注入 vs 手动获取

  • 自动注入@Autowired/@Resource):

    • 优点:代码简洁,符合依赖注入原则,无需显式查找 Bean。
    • 缺点:灵活性低,无法动态选择 Bean(如根据条件)。
    • 最佳实践:优先使用,适合常规场景。
  • 手动获取getBean()/ApplicationContextAware):

    • 优点:灵活,支持动态选择 Bean。
    • 缺点:代码侵入性高,可能破坏依赖注入原则。
    • 适用场景:必须动态选择 Bean(如多环境配置)或在非 Spring 管理的类中使用。

2. 类型匹配 vs 名称匹配

  • @Autowired:按类型匹配,若存在多个同类型 Bean 需结合 @Qualifier 指定名称。
  • @Resource:默认按名称匹配,更明确且跨框架兼容(如 JEE 环境)。

3. 性能与可测试性

  • 自动注入:性能高,因为 Spring 启动时已完成依赖注入,测试时可通过 Mock 框架(如 Mockito)模拟依赖。
  • 手动获取:可能需要额外的上下文模拟,测试复杂度较高。

4. 全局访问的陷阱

  • ApplicationContextAware
    • 优点:提供全局访问 ApplicationContext 的能力。
    • 缺点:隐藏依赖,增加耦合,可能导致代码难以维护。
    • 最佳实践:仅在必要时(如工具类)使用,并限制其范围。

2.3 推荐使用场景

场景推荐方式
常规 Bean 注入(类型唯一)@Autowired 或 @Resource
需要明确指定 Bean 名称时@Resource
动态选择 Bean(如多环境配置)ApplicationContext.getBean()
需要全局访问 ApplicationContextApplicationContextAware
非 Spring 管理的类中获取 BeanApplicationContext 传递

最佳实践总结

  1. 优先使用依赖注入@Autowired/@Resource),遵循“依赖注入优于查找”的原则。
  2. 避免滥用 getBean():仅在必须动态选择或非 Spring 管理的场景使用。
  3. 谨慎使用全局上下文(如 ApplicationContextAware),防止过度耦合。
  4. 明确 Bean 唯一性:若存在多个同类型 Bean,使用 @Qualifier 或 @Resource 显式指定名称。

3. 相关文档

Spring中生成Bean的方式总结-笔记-CSDN博客

相关文章:

  • JR6001语音模块详解(STM32)
  • 【安全扫描器原理】ICMP扫描
  • 前端安全中的XSS(跨站脚本攻击)
  • 服务器和数据库哪一个更重要
  • 不同类型插槽的声明方法和对应的调用方式
  • k8s集群环境部署业务系统
  • 服务器主动发送响应?聊天模块如何实现?
  • 深入理解Spring AI框架的核心概念
  • 首款 AI 固定资产管理系统,引领管理新变革
  • Python return 语句
  • mangodb的数据库与集合命令,文档命令
  • UVA1537 Picnic Planning
  • java 解析入参里的cron表达式,修改周时间
  • 链表的中间节点
  • JavaScript高级进阶(五)
  • HTTP协议重定向及交互
  • UniApp页面路由详解
  • AbortController 取消请求
  • C++23 std::byteswap:反转字节 (P1272R4)
  • 征战高端10余载,OPPO少了昔日的锐气
  • 日趋活跃!2024年我国数据生产总量同比增长25%
  • 商务部:4月份以来的出口总体延续平稳增长态势
  • 国家发改委:建立实施育儿补贴制度
  • 伊朗港口爆炸致18死800余伤,三分之二伤者已出院
  • 规范涉企案件审判执行工作,最高法今天发布通知
  • 大家聊中国式现代化|周冯琦:转角见美,让“绿意”触手可及