Spring框架中,@Resource注解和@Autowired注解的区别

49 篇文章 1 订阅
3 篇文章 0 订阅

平时开发中,我们知道,spring中,@Resource和@Autowired都是可以在bean的注入时使用。这里简单介绍一下@Resource和@Autowired注解:

  1. @Resource有两个常用属性name、type,注入时分4种情况:
  • 指定name和type:通过name找到唯一的bean,找不到抛出异常;如果type和字段类型不一致,也会抛出异常;
  • 指定name:通过name找到唯一的bean,找不到抛出异常;
  • 指定type:通过tpye找到唯一的bean,如果不唯一,则抛出异常;
  • 都不指定:通过字段名作为key去查找,找到则赋值;找不到则再通过字段类型去查找,如果不唯一,则抛出异常。
  1. @Autowired只有一个属性required,默认值为true,为true时,找不到就抛异常,为false时,找不到就赋值为null
  • @Autowired按类型查找,如果该类型的bean唯一,直接注入,如果不唯一,并不一定会报错,而是按照字段名字推断选择哪个bean;可通过注解@Qualifier配合使用解决,也可以指定字段名称和实例名称一致,这时不需要借助@Qualifier注解。

不过它们之间有什么区别呢,下面先用代码演示一下,为了方便演示,这个快速创建一个spring boot项目,项目结构如下:

在这里插入图片描述
为了测试,创建一个空的TestService文件:

public class TestService {
}

在TestConfig中,生成两个TestService的实例对象:

@Configuration
public class TestConfig {
    
    @Bean
    //@Bean("firstService")
    public TestService firstService() {
        return new TestService();
    }

    @Bean
    //@Bean("secondService")
    public TestService secondService() {
        return new TestService();
    }
}

注意:使用@Bean注解,不指定生成实例名称时,默认就是方法名

下面进行测试:

首先测试@Resource注解:

  1. 测试字段名称和实例名称不符(不指定):
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Resource
    private TestService testService1;
    @Resource
    private TestService testService2;

   @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,出现异常

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.learn.service.TestService' available: expected single matching bean but found 2: FirstService,secondService
  1. 测试字段名称和实例名称不符(指定):
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Resource(name = "firstService")
    private TestService testService1;
    @Resource(name = "secondService")
    private TestService testService2;

    @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,未出现异常

done!
  1. 测试字段名称和实例名称相同:
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Resource
    private TestService firstService;
    @Resource
    private TestService secondService;

    @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,未出现异常

done!

接着,测试一下@Autowired注解:

  1. 测试字段名称和实例名称不符(不指定):
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Autowired
    private TestService testService1;
    @Autowired
    private TestService testService2;

    @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,出现异常

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.learn.service.TestService' available: expected single matching bean but found 2: firstService,secondService
  1. 测试字段名称和实例名称不符(指定),此时@Autowired需要跟 @Qualifier注解配合使用:
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Qualifier("firstService")
    @Autowired
    private TestService testService1;
    @Qualifier("secondService")
    @Autowired
    private TestService testService2;

    @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,未出现异常

done!
  1. 测试字段名称和实例名称相同:
@SpringBootTest
class SpLearnResourceAndAutowiredApplicationTests {

    @Autowired
    private TestService firstService;
    @Autowired
    private TestService secondService;

    @Test
    void contextLoads() {
        System.out.println("done!");
    }
}

测试结果,未出现异常

done!

通过以上测试结果和其他搜集的资料,总结一下@Resource注解和@Autowired注解的相同点和不同点:

相同点:

  1. Spring中都可以使用;
  2. 都可以作用在字段和setter方法上;
  3. 当字段名称和实例名称相同时,两者作用相似。

不同点:

  1. @Resource是JDK提供的,而@Autowired是Spring提供的;
  2. @Resource不允许找不到bean的情况,而@Autowired允许(@Autowired(required = false));
  3. 指定name的方式不一样,@Resource(name = “beanName”),@Autowired需要借助@Qualifier(“beanName”)注解;
  4. @Resource默认通过name查找,找不到则通过字段类型去查找,而@Autowired默认通过type查找,如果找到的bean不唯一,则再通过字段名称推断相应的bean。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值