Spring @Qualifier的匹配范围、复用及批量配置技术疑问
1. Spring查找Bean的范围
答案很明确:Spring会先根据你要注入的目标类型(比如这里的Reader),筛选出所有属于该类型的Bean实例,之后才会在这个筛选后的集合里匹配@Qualifier指定的标识,不会在全局所有Bean里乱找。
拿你的代码举例,当注入private Reader reader时,Spring第一步会把所有实现了Reader接口的Bean(也就是LocalFileReader和DbReader)挑出来,第二步再在这两个Bean里找带有@Qualifier("LocalFileReader")的那个,最后完成注入。
2. 不同类型Bean能否共用相同的@Qualifier值
完全可以。因为前面说了,Spring是先按类型筛选,再匹配Qualifier。
比如你给Reader的本地文件实现和Writer的本地文件实现都加@Qualifier("LocalFile"):
@Component @Qualifier("LocalFile") public class LocalFileReader implements Reader { } @Component @Qualifier("LocalFile") public class LocalFileWriter implements Writer { }
在MyService里注入时:
public class MyService { @Autowired @Qualifier("LocalFile") private Reader reader; @Autowired @Qualifier("LocalFile") private Writer writer; }
注入Reader时,Spring只会在Reader类型的Bean里找带"LocalFile"标识的,也就是LocalFileReader;注入Writer时则只会在Writer类型里找,也就是LocalFileWriter,两者完全不会冲突。
3. 一次性指定使用同组Bean的方案
最优雅的方式是自定义限定符注解,把同组的标识封装成一个注解,避免重复写字符串,还能统一管理:
步骤1:定义自定义限定符注解
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier // 必须加上这个元注解,让Spring识别这是个限定符 public @interface LocalFile { }
步骤2:给同组Bean添加该注解
@Component @LocalFile public class LocalFileReader implements Reader { } @Component @LocalFile public class LocalFileWriter implements Writer { }
步骤3:在Service中使用该注解注入
public class MyService { @Autowired @LocalFile private Reader reader; @Autowired @LocalFile private Writer writer; }
这样一来,所有标注了@LocalFile的Bean都属于同一组,注入时直接用这个注解就能匹配到对应类型的同组Bean,不用每次写重复的字符串,后期修改也更方便。
另外,如果你的Service需要批量注入同组的Bean(比如所有本地文件类型的Reader),也可以这么写:
@Autowired @LocalFile private List<Reader> localFileReaders;
内容的提问来源于stack exchange,提问作者Calimero

