使用 @Autowired 注解是 Spring 依赖注入的绝好方法。但是有些场景下仅仅靠这个注解不足以让Spring知道到底要注入哪个 bean。 默认情况下,@Autowired 按类型装配 Spring Bean。 如果容器中有多个相同类型的 bean,则框架将抛出 NoUniqueBeanDefinitionException, 以提示有多个满足条件的 bean 进行自动装配。程序无法正确做出判断使用哪一个,下面就是个鲜活的例子:

  1. @Component("fooFormatter")
  2. public class FooFormatter implements Formatter {
  3. public String format() {
  4. return "foo";
  5. }
  6. }
  7. @Component("barFormatter")
  8. public class BarFormatter implements Formatter {
  9. public String format() {
  10. return "bar";
  11. }
  12. }
  13. @Component
  14. public class FooService {
  15. @Autowired
  16. private Formatter formatter;
  17. //todo
  18. }
  19. 复制代码

如果我们尝试将 FooService 加载到我们的上下文中,Spring 框架将抛出 NoUniqueBeanDefinitionException。这是因为 Spring 不知道要注入哪个 bean。为了避免这个问题,有几种解决方案。那么我们本文要讲解的 @Qualifier 注解就是其中之一。跟着小胖哥的节奏往下走。

3. @Qualifier

通过使用 @Qualifier 注解,我们可以消除需要注入哪个 bean 的问题。让我们重新回顾一下前面的例子,看看我们如何通过包含 @Qualifier 注释来指出我们想要使用哪个 bean 来解决问题:

  1. @Component
  2. public class FooService {
  3. @Autowired
  4. @Qualifier("fooFormatter")
  5. private Formatter formatter;
  6. //todo
  7. }
  8. 复制代码

通过将 @Qualifier 注解与我们想要使用的特定 Spring bean 的名称一起进行装配,Spring 框架就能从多个相同类型并满足装配要求的 bean 中找到我们想要的,避免让Spring脑裂。我们需要做的是@Component或者@Bean注解中声明的value属性以确定名称。 其实我们也可以在 Formatter 实现类上使用 @Qualifier 注释,而不是在 @Component 或者 @Bean 中指定名称,也能达到相同的效果:

  1. @Component
  2. @Qualifier("fooFormatter")
  3. public class FooFormatter implements Formatter {
  4. public String format() {
  5. return "foo";
  6. }
  7. }
  8. @Component
  9. @Qualifier("barFormatter")
  10. public class BarFormatter implements Formatter {
  11. public String format() {
  12. return "bar";
  13. }
  14. }

作者:码农小胖哥
链接:https://juejin.im/post/6844904035342893063
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。