Sprint Boot————@Qualifier、@Primary

引言

使用@Autowired自动注入时:

如果注入的接口有多个实现类,如下所示:

那么如果不指定具体是哪个实现类的Bean,在Spring Boot启动时就会发生异常(下图请点击查看):

 异常的描述信息非常简单,就是告诉开发者,自动注入的地方需要一个Bean,而spring 容器却找到了3个实现类的Bean。

Action(可以采取的行动): 考虑使用@Primary注解或@Qualifier注解。

 

@Primary

此注解用在类上面,官方解释如下:

简单翻译过来就是,这个注解相当于Spring 的xml配置文件中bean标签里的 primary属性。

它表示在需要自动注入一个单值依赖的地方,却有多个候选依赖,那么这个注解会指定一个类作为preference(偏好)选择。

可以简单理解为,我们把@Primary注解标记在任意一个类上面,在使用@Autowired注入的时候,如果不特殊指明(如何特殊指明请看@Qualifier的讲解),那么默认就注入被@Primary标记的类。

但是只可以指定一个类作为偏好类,否则依然会产生冲突。

@Qualifier

此注解用在属性上、方法上、参数上等,官方解释如下:

翻译过来就是说,这个注解用在属性上,或参数上,在自动注入的时候作为多个候选bean的限定。也可以使用在其他的随后会被用于限定bean的定制注解上。

其实大多数用于属性上和@Autowired一起联用。

这个注解有一个参数:

(default关键字应该是java8中引入的关键字,不过我也是第一次见过这种写法,可能是孤陋寡闻,各位大神轻喷)

稍微思考一下就可以猜到,如果不为@Qualifier注解指定参数那么默认使用类的默认别名,即类的首字母小写,比如:

ChineseTeacher类的默认别名是:chineseTeacher;

EnglishTeacher类的默认别名是:englishTeacher;

MathTeacher类的默认别名是:mathTeacher。

 使用默认别名的方法很简单,直接用类的默认别名来命名我们的自动注入对象,如下所示:

Teacher接口有三个实现类:ChineseTeacher、EnglishTeacher、MathTeacher,我们不需要使用@Primary,也不使用@Qualifier,直接在自动注入的变量上使用默认别名,依然可以注入成功。

是的,当我们在自动注入的时候使用类的默认别名,就不会发生候选Bean冲突的问题。

使用@Qualifier或@Primary注解仅仅是在你不想用默认别名来命名注入的bean或是忘记了使用默认别名的情形。

当我们不使用默认别名来使用自动注入功能,我们就需要使用@Qualifier来指定选择的类型,像下面这样:

注意,如果想将ChineseTeacher注入到teacher对象中,就必须给ChineseTeacher类设置别名。

@Service、@Component等注解都可以传入一个字符串作为类的别名。

注意:使用@Qualifier注入bean的时候,它所选取的类的别名需要与具体的类的别名一致,否则会报无法找到指定类型的错误。

 总结

罗里吧嗦说了这么多,其实总结起来很简单。

我们自动注入的时候,如果有多个候选实现类的bean,spring boot启动的时候就不知道该选择哪个bean进行注入,因此会报错。

使用@Primary可以指定一个首选Bean注入;使用@Qualifier可以在自动注入的地方通过传入一个限定名(也就是类的别名)来选取指定的实现类,只不过必须与类的别名一致(如果不传限定名,就使用类的默认别名)

如果既不用@Primary也不用@Qualifier,那就必须在自动注入的时候直接以类的默认别名来命名。

给(spring ioc容器管理的)类设置别名的方式是:@Service("别名")、@Component("别名") 、@Bean("别名") 等等。

 

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页