spring @Resource @Autowired @qualifier

本文深入探讨Spring框架中@Autowired和@Resource注解的使用区别,包括它们的装配策略、默认行为及如何指定装配方式。同时,文章介绍了@Qualifier和@Primary注解在解决依赖冲突时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、

@PostConstruct以及@PreDestroy。

一.@Resource
  @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入

罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字

,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使

用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
  @Resource装配顺序
  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始

类型进行匹配,如果匹配则自动装配;

二.@Autowired 与@Resource的区别:
1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

2、 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许

null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结

合@Qualifier注解进行使用,如下:

@Autowired
@Qualifier("baseDao")
private BaseDao baseDao;

如果直接使用

@Autowired
private BaseDao baseDao;

那么其默认的beanName为baseDaoImpl(实现类名字,开头小写);
@Resource 默认的name也是一样的;
其中IDEA可以识别标注的name存不存在;(编译检查)
所以在接口只要一个实现类的情况下,可以直接使用@Autowired

3、@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定

name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装

配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名

称进行装配。
注:默认情况可能会2次查找,性能会低些;

三 @qualifier作用
1.限定匹配bean
2.也支持逻辑限定,即可以修饰注解,如@LoadBalanced
详见:https://www.cnblogs.com/fangshixiang/p/11532717.html

四.@Primary :优先考虑注入的类,比如两个类继承了同一个接口,然后注入的时候是以接口名的形式注入到另一个

类中的。 这个时候会报一下错误:

Unsatisfied dependency expressed through field ‘animal’; nested exception is

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type

‘com.hbr.three.Animal’ available: expected single matching bean but found 2: dog,panda

也就是说,animal接口没有唯一的bean定义。本来想找一个bean的,可是却发现了两个,dog和panda. 然后就不知道

带注入哪个实例了,然后就报错了。

被注入的类是这样的:

@Component
public class DIclass {

@Autowired
private  Animal animal;

public void eat(){
    animal.eat();
}

}
然后dog和panda实现了animal的接口。

测试里面是这样的:

AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Configurate.class);
DIclass bean = (DIclass)app.getBean(“DIclass”);
bean.eat();
这里注意,包扫描的beanname是类名一致,没有首字母小写的,不要和@bean注解默认的名字搞混了。
所以这个时候 @Primary 注解就发挥作用了,它会优先考虑有这个注解的类。

参考:https://www.cnblogs.com/fengli9998/p/7472247.html

<think>嗯,用户想了解@Resource@Autowired注解的区别,这两个在Spring中都是用来做依赖注入的。首先,我需要回忆一下这两个注解的基本特性和用法。 首先,我记得@AutowiredSpring框架自己的注解,而@Resource是Java标准库里的,属于JSR-250的一部分。所以它们的来源不同,可能在使用范围上也有差异。比如,如果项目没有用Spring,可能就用不了@Autowired,但@Resource可能在别的框架里也能用。 然后,默认的注入方式。@Autowired默认是按类型(byType)来注入的,也就是根据接口或者类的类型去找匹配的Bean。而@Resource默认是按名称(byName),也就是根据Bean的名字来匹配。不过@Resource也可以指定name属性来明确使用哪个Bean,这时候可能更灵活一点。 还有,关于使用场景。如果项目里同一个接口有多个实现类,这时候用@Autowired可能需要配合@Qualifier来指定具体的Bean名称,而@Resource可以直接用name属性来指定。这样可能在某些情况下更方便。 另外,@Autowired可以用在构造器、方法、字段上,而@Resource通常用在字段和方法上,构造器可能不支持?这点需要确认一下。比如,Spring的文档里有没有说@Resource不能用在构造器上? 还有required属性,@Autowired可以设置required=false,这样即使找不到Bean也不会报错,而@Resource好像没有这个属性,可能默认就是必须的,如果找不到就会报错? 然后要检查引用中的内容是否正确。比如引用2提到@Resource只能用于变量和设置方法,而@Autowired可以用在构造器、变量、设置方法。所以用户可能需要知道在构造器注入时,只能用@Autowired或者@Inject这些。 还有,当有多个同类型的Bean时,@Autowired需要配合@Qualifier,而@Resource可以用name属性来解决。这种情况下,两者的使用方式不同,但都能达到目的。 还需要考虑使用场景的选择。比如,如果项目已经大量使用Spring,可能更倾向于@Autowired,因为它和Spring整合得更好。而如果需要更通用的注解,或者项目中有其他JSR-250的支持,可能用@Resource更好。 另外,错误处理方面,@Autowired默认必须找到Bean,否则抛异常,而@Resource是否也是这样?根据引用3,@Autowired可以设置required=false,而@Resource可能没有这个选项,所以如果找不到的话就会直接报错,除非有默认的名称匹配。 总结一下,两者的主要区别在于来源、默认注入方式、使用位置、以及如何解决多个Bean的情况。需要把这些点整理清楚,用用户容易理解的语言表达出来,并且结合引用中的内容,确保准确性。</think>### Java Spring@Resource@Autowired的区别详解 #### 1. **来源与标准支持** - **@Autowired** 是Spring框架特有的注解,仅适用于Spring容器管理的Bean。它通过类型(byType)进行依赖注入,若需按名称匹配需结合`@Qualifier`注解[^2]。 - **@Resource** 属于Java标准库(JSR-250规范),不依赖特定框架。默认按名称(byName)注入,支持通过`name`属性指定Bean名称[^2]。 #### 2. **默认注入方式** - **@Autowired** ```java @Autowired private UserService userService; // 按类型匹配 ``` 若存在多个同类型Bean,需配合`@Qualifier`指定名称: ```java @Autowired @Qualifier("userServiceImplA") private UserService userService; ``` - **@Resource** ```java @Resource private UserService userService; // 默认按字段/方法参数名匹配 ``` 也可显式指定名称: ```java @Resource(name = "userServiceImplA") private UserService userService; ``` #### 3. **使用范围** - **@Autowired** 支持**构造器、字段、设置方法(setter)**。例如构造器注入: ```java @Autowired public UserController(UserService userService) { this.userService = userService; } ``` - **@Resource** 仅支持**字段、设置方法**,**不支持构造器注入**[^2]。 #### 4. **错误处理与灵活性** - **@Autowired** 默认要求依赖必须存在,否则抛出`NoSuchBeanDefinitionException`。可通过`required=false`允许注入失败: ```java @Autowired(required = false) private Optional<UserService> userService; // 依赖非必需 ``` - **@Resource** 无类似`required`属性,若未找到指定名称的Bean,直接抛出异常。 #### 5. **适用场景对比** | **场景** | **推荐注解** | **说明** | |-----------------------------|-------------------|-------------------------------------------------------------------------| | 按类型注入 | `@Autowired` | 适合单实现类或配合`@Qualifier`指定名称 | | 按名称注入 | `@Resource` | 直接通过名称匹配,代码更简洁 | | 多实现类需指定Bean | 两者均可 | `@Autowired + @Qualifier`或`@Resource(name="...")` | | 非Spring环境 | `@Resource` | 依赖Java标准库,兼容性更强 | #### 6. **代码示例对比** ```java // 使用@Autowired按类型注入 @Service public class ServiceA { @Autowired private Repository repository; } // 使用@Resource按名称注入 @Service public class ServiceB { @Resource(name = "mysqlRepository") private Repository repository; } ``` #### 总结 - **框架依赖**:`@Autowired`绑定Spring,`@Resource`与框架无关。 - **注入策略**:`@Autowired`默认按类型,`@Resource`默认按名称。 - **灵活性**:`@Autowired`支持构造器注入和可选依赖,`@Resource`名称控制更直接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值