您当前的位置: 首页 > 

程序员一灯

暂无认证

  • 3浏览

    0关注

    152博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

@Autowired @Qualifier 、 @Inject、@Resource 的区别

程序员一灯 发布时间:2021-12-02 23:55:57 ,浏览量:3

@Inject: 这是jsr330 的规范,通过AutowiredAnnotationBeanPostProcessor 类实现的依赖注入。位于javax.inject包内,是Java自带的注解。 可以通过byName注入

@Inject
@Named("environment")
Environment env;

 注:如果不加@Named注解,需要配置与变量名一致即可。

@Autowired: Spring提供的注解,通过AutowiredAnnotationBeanPostProcessor 类实现注入。位于org.springframework.beans.factory.annotation 包内。

将构造函数、字段、setter 方法或配置方法标记为由 Spring 的依赖注入工具自动装配。 这是 JSR-330 javax.inject.Inject注释的替代方法,添加了 required-vs-optional 语义。

可以通过byName注入

@Autowired
Environment env;

 

注:默认是通过byType 实现注入

@Resource: @Resource 是jsr250规范的实现,通过CommonAnnotationBeanPostProcessor 类实现注入。@Resource 一般会指定一个name属性,如下:

Resource 注解标记了应用程序需要的资源。

@Resource(name = "environment")
Environment env;

注:默认是通过byName 实现注入

区别:

1、@Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理依赖注入

但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。当然,两者都是BeanPostProcessor。

2、@Resource 是J2EE的注解  @Autowire 是Spring的注解

3、@Resource默认通过反射ByName注入,但是如果声明了Type属性,通过By Type注入 如果生命了Name属性,通过By Name注入

Spring 注解 @Qualifier 详细解析

1. 概述

今天带你了解一下 Spring 框架中的 @Qualifier 注解,它解决了哪些问题,以及如何使用它。我们还将了解它与 @Primary 注解的不同之处。

2. 问题

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

    @Component("fooFormatter")
    public class FooFormatter implements Formatter {
        public String format() {
            return "foo";
        }
    }

    @Component("barFormatter")
    public class BarFormatter implements Formatter {
        public String format() {
            return "bar";
        }
    }

    @Component
    public class FooService {
        @Autowired
        private Formatter formatter;
        
        //todo 
    }

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

3. @Qualifier

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

 @Component
    public class FooService {
        @Autowired
        @Qualifier("fooFormatter")
        private Formatter formatter;
        
        //todo 
    }

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

     @Component
     @Qualifier("fooFormatter")
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }
 
     @Component
     @Qualifier("barFormatter")
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }
4. @Qualifier VS @Primary

还有另一个名为 @Primary 的注解,我们也可以用来发生依赖注入的歧义时决定要注入哪个 bean。当存在多个相同类型的 bean 时,此注解定义了首选项。除非另有说明,否则将使用与 @Primary 注释关联的 bean 。 我们来看一个例子:

@Bean
    public Employee tomEmployee() {
        return new Employee("Tom");
    }

    @Bean
    @Primary
    public Employee johnEmployee() {
        return new Employee("john");
    }

在此示例中,两个方法都返回相同的 Employee类型。Spring 将注入的 bean 是方法 johnEmployee 返回的 bean。这是因为它包含 @Primary 注解。当我们想要指定默认情况下应该注入特定类型的 bean 时,此注解很有用。 如果我们在某个注入点需要另一个 bean,我们需要专门指出它。我们可以通过 @Qualifier 注解来做到这一点。例如,我们可以通过使用 @Qualifier 注释来指定我们想要使用 tomEmployee 方法返回的 bean 。 值得注意的是,如果 @Qualifier 和 @Primary 注释都存在,那么 @Qualifier 注释将具有优先权。基本上,@Primary 是定义了默认值,而 @Qualifier 则非常具体。 当然@Component 也可以使用@Primary 注解,这次使用的还是上面3的示例:

@Component
     @Primary
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }
 
     @Component
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }

在这种情况下,@Primary 注解指定了默认注入的是 FooFormatter,消除了场景中的注入歧义。

5. 通过名称来自动注入

在使用 @Autowired 进行自动装配时,如果 Spring 没有其他提示,将会按照需要注入的变量名称来寻找合适的 bean。也可以解决依赖注入歧义的问题。让我们看一些基于我们最初的例子的代码:

 @Component
    public class FooService {
        @Autowired
        private Formatter fooFormatter;
        
        //todo 
    }

在这种情况下,Spring 将确定要注入的 bean 是 FooFormatter,因为字段名称与我们在该 bean 的 @Component或者 @Bean 注解中使用的值(默认 @Bean 使用方法名)相匹配。

6. 总结

通过对 @Qualifier 的探讨,我们知道该注解是用来消除依赖注入冲突的。这种在日常开发中很常见。

关注
打赏
1645367472
查看更多评论
立即登录/注册

微信扫码登录

0.0388s