环境:6.2.0-SNAPSHOT
1. 简介
当Spring容器中存在多个相同类型的Bean,并且需要确定在自动装配时应该使用哪个Bean时,@Primary注解就派上了用场。如下示例:
public interface CommonDAO {}public class UserDAO implements CommonDAO {}public class PersonDAO implements CommonDAO {}public class CommonService {private CommonDAO dao ;public CommonService(CommonDAO dao) {this.dao = dao ;}}@Configurationpublic class Module1Config {@Beanpublic UserDAO userDAO() {return new UserDAO() ;}@Beanpublic CommonService commonService(CommonDAO dao) {return new CommonService(dao) ;}}@Configurationpublic class Module2Config{@Bean@Primarypublic PersonDAO personDAO() {return new PersonDAO() ;}}
当有多个Bean时,使用@Primary不是唯一的方法,其它方法请查看如下文章
有时,我们希望能够在不破坏现有代码的情况下注册一个给定类型的 Bean,尤其是在多模块项目中。就如上面的代码,如果让你不改动现有代码的情况下,我们希望在新增模块时,只有在原来的Bean缺失的情况下,新增模块中的Bean生效,通过上面@Primary是没法实现的。从Spring6.2开始新增了一个注解,可以用来解决该问题。
2. 新特性Fallback
Spring6.2新增了一个@Fallback注解,该注解表示该 bean 符合备用自动装配候选条件,这是 @Primary 注释的替代品。如果多个匹配候选者中只有少数几个被标记为fallback,则剩余的 bean 将被选中。与Primary bean 一样,备用 bean 仅在查找单个注入点的多个候选者时起作用。在自动装配数组、集合、映射或 ObjectProvider 流时,所有类型匹配的 bean 都将被包括在内。使用示例如下:
public class AppConfig {public UserDAO userDAO() {return new UserDAO() ;}public PersonDAO personDAO() {return new PersonDAO() ;}public CommonService commonService(CommonDAO dao) {return new CommonService(dao) ;}}
上面的示例中,CommonService注入的是UserDAO。当UserDAO Bean不存在时,才会注入PersonDAO。
如果定义多个@Fallback而没有默认的,那么针对单注入点是会报错。
public UserDAO userDAO() {return new UserDAO() ;}public PersonDAO personDAO() {return new PersonDAO() ;}
如果两个bean分别由@Fallback与@Primary标注,@Primary优先级高
public UserDAO userDAO() {}public PersonDAO personDAO() {}
注意:
从6.2版本开始Bean的自动装配算法略有修改,在一组按类型匹配的候选 Bean 中,参数名称匹配和 @Qualifier("...")匹配(针对目标 Bean 名称)会推翻 @jakarta.annotation.Priority 排序,而以前是反过来检查的。总结如下:
从6.2开始,如果有多个符合条件的bean时,依赖注入的查找顺序如下:
@Primary(这里会先找@Primary,然后再从非@Fallback中查找)
根据字段名称或参数名(按照名称)
@Qualifier限定名,指定的value名称
@Priority
选择直接注册的依赖项(在定义BeanFactory时就提起定义好某个类型注入的时候使用的类)
而在6.2之前版本,依赖注入的查找顺序如下:
@Primary
@Priority
选择直接注册的依赖项
上面所说的直接注册的依赖项,就是通过如下方式静态注册
// 手动创建BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory() ;beanFactory.registerResolvableDependency(CommonDAO.class, TeacherDAO.class) ;
以上是本篇文章的全部内容,如对你有帮助就请作者吃个棒棒糖🍭。
完毕!!!
推荐文章
实战Spring Cloud Gateway自定义谓词及网关过滤器
SpringBoot整合Flink CDC,实时追踪数据变动,无缝同步至Redis



