@Qualifier、@Autowired、@Resource的区别

@Qualifier

@Qualifier 可以让程序员明确指明需要那个bean,我们直接看代码
User类

public interface User {
}

User1类

@Component
public class User1 implements User{
}

User2类

@Component
public class User2 implements User{
}

UserService类

@Component
public class UserService {

    @Autowired
    private User user;

    public void test() {
        System.out.println(user);
    }
}

DemoApplication类main方法

public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.shadow.anno.demo");
        UserService userService = applicationContext.getBean(UserService.class);
        userService.test();
    }

运行后我们会看到如下错误信息

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'user'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.shadow.anno.demo.User' available: expected single matching bean but found 2: user1,user2
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:598)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1404)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:860)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:101)
	at com.shadow.anno.demo.DemoApplication.main(DemoApplication.java:13)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.shadow.anno.demo.User' available: expected single matching bean but found 2: user1,user2
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:221)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1249)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1191)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595)
	... 14 more

这是由于我们程序中User类有User1和User2类两个实现,spring注入时会找到多个bean,于是报错,这里我们可以有集中解决方案:

  1. 给User1或User2类添加@Primary(这里在User1上添加,便于区分)
@Component
@Primary
public class User1 implements User{
}

我们运行后看到可以正常打印user的值,值为User1对象的实例
在这里插入图片描述

  1. 给UserService的user属性添加@Qualifier(这里用user2),并标明要使用的beanName,修改后如下代码
@Component
public class UserService {

    @Autowired
    @Qualifier("user2")
    private User user;

    public void test() {
        System.out.println(user);
    }
}

我们运行后看到可以正常打印user的值,值为User2对象的实例
在这里插入图片描述

@Autowired

@Autowired注入是先byType,如果找到多个bean之后再进行byName,也就是说,他优先根据类型进行注入,当找到多个bean时,再根据name来进行注入,它是由Spring提供的注解,由AutowiredAnnotationBeanPostProcessor类来解析的,解析代码在postProcessMergedBeanDefinition方法中,他可以写在构造方法、普通方法(静态方法无效)、方法参数、属性(静态属性无效)、注解上

@Resource

@Resource注入是byName,它是由jdk提供的注解,由CommonAnnotationBeanPostProcessor类来解析,解析代码在postProcessMergedBeanDefinition方法中,他可以写在类、普通方法(静态方法无效)、属性(静态属性无效)上

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@Qualifier和@AutowiredSpring框架中的注解,用于实现依赖注入。@Autowired注解可以单独使用,它按照类型进行装配。但是如果容器中存在多个相同类型的bean,@Autowired无法确定要注入哪个bean,会出现问题。这时可以使用@Qualifier注解与@Autowired一起使用,通过指定bean的名称来明确要注入的bean。例如,可以使用@Qualifier("baseDao")来指定要注入的BaseDao类型的bean。\[2\] @Qualifier和@AutowiredSpring框架中的弹簧注解,而@Resource是标准的Java注解(来自JSR-250)。此外,@Resource只支持字段和setter方法的注入,而@Autowired支持字段、setter方法、构造函数和多参数方法的注入。\[3\] #### 引用[.reference_title] - *1* [看完让你吊打面试官-@Autowired注解到底怎么实现的?](https://blog.csdn.net/qq_33589510/article/details/105071416)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring中@Autowired、@Qualifier、@Resource区别](https://blog.csdn.net/riemann_/article/details/103755251)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值