@Autowired与@Resource区别

每当问到@Autowired和@Resource有什么区别时,我们总会不假思索的答到:@Autowired是按照类型注入,@Resource是按照名称注入。这种说法不能说错,只能说答的不全面,那要如何使自己的回答让人眼前一亮呢,且听我慢慢道来。

@Autowired

@Autowired默认按照类型byType注入,如果按照类型注入时,匹配到多个结果,就会按照名称byName注入(ps:所以@Autowired也可以按照名称注入哟)。

当@Autowired通过byName进行注入时,会获取属性的name进行匹配,例如:

@Autowired
private UserService userService;

获取到的名字就是userService,将获取到的属性名称userService与前面通过类型匹配但匹配到多个bean进行name比对,如果匹配出唯一结果,则结束;如果还是匹配出多个结果,则抛异常
NoUniqueBeanDefinitionException。

@Resource

@Resource默认按照byName进行属性注入,如果通过name无法找到相应的bean实例,接着就通过byType进行匹配。按照byType匹配的逻辑和@Autowired匹配走的是同一套逻辑,所以@Resource的匹配逻辑为byName -> byType -> byName。

到此为止,两个注解的注入原理基本解释清楚了,如果只是获取结论,就可以溜了~~~

@Autowired与@Resource区别

结论验证

接下来将通过代码对以上结论进行验证

定义一个用户服务接口

public interface UserService {
	void getName();
}

定义用户服务接口的两个实现类UserServiceImpl1和UserServiceImpl2

@Service
public class UserServiceImpl1 implements UserService{
	@Override
	public void getName() {
		System.out.println("UserService1Impl");
	}
}
@Service
public class UserServiceImpl2 implements UserService {
	@Override
	public void getName() {
		System.out.println("userServiceImpl2");
	}
}

定义一个用户Controller

@RestController
public class UserController {
	@Autowired
	private UserService userService;

	public void getName(){
		userService.getName();
	}
}

定义一个main方法进行服务调用

@ComponentScan("com.lr.interfaces.byResource")
public class AppConfig {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		// 获取bean工厂BeanFactory获取UserController
    UserController userController = context.getBean(UserController.class);
		userController.getName();
	}
}

1.验证@Autowired的注入

(1)测试1:当UserServiceImpl1和UserServiceImpl2同时存在,在UserController采用以下注入方式,必然会报错,因为@Autowired先按照byType匹配,匹配到了“userServiceImpl1”和“userServiceImpl2”,结果不唯一,只能按照byName注入,此时的name为“userService”,结果无法唯一确定,只能抛出异常。(ps:byType和byName都无法注入)

@Autowired
private UserService userService;

(2)测试2:当UserServiceImpl1和UserServiceImpl2同时存在,此时相比测试1的区别是“userService”改为了“userServiceImpl1”,这次就能正确执行,并且输出结果为“userServiceImpl1”。(ps:byType查找到多个示例,通过byName注入)

@Autowired
private UserService userServiceImpl1;

(3)测试3:当UserServiceImpl1和UserServiceImpl2同时存在,但此时我就想使用测试1中的“userService”该怎么办呢?这时候我们可以采用另一个注解@Qualifier来指定注入的名称,此时也能正确输出结果“userServiceImpl1”。(ps:byType查找到多个示例,通过byName注入)

@Autowired
@Qualifier("userServiceImpl1")
private UserService userService;

(4)测试4:当只有一个接口实现类UserServiceImpl1,毫无疑问,按照类型就能注入,打印的结果也是“userServiceImpl1”,这也是我们平时见过的最多的实现。(ps:byType注入)

2.验证@Resource的注入

(1)测试1:当UserServiceImpl1和UserServiceImpl2同时存在,在UserController采用以下注入方式,必然会报错。因为@Resource先按照byName匹配,此时的name是“userService”,没有匹配结果,只能按照byType进行配置,此时又匹配到了“userServiceImpl1”和“userServiceImpl2”,结果不唯一,只能抛出异常。(ps:byName和byType都无法注入)

@Resource
private UserService userService;

(2)测试2:当UserServiceImpl1和UserServiceImpl2同时存在,此时相比测试1的区别是“userService”改为了“userServiceImpl1”,这次就能正确执行,并且输出结果为“userServiceImpl1”。(ps:通过byName匹配到了唯一的bean实例)

@Resource
private UserService userServiceImpl1;

(3)测试3:当UserServiceImpl1和UserServiceImpl2同时存在,但此时我就想使用测试1中的“userService”该怎么办呢?这时候我们可以在@Resource注解中指定注入的名称,此时也能正确输出结果“userServiceImpl1”。(ps:通过byName匹配到了唯一的bean实例)

@Resource(name = "userServiceImpl1")
private UserService userService;

(4)测试4:当只有一个接口实现类UserServiceImpl1,采用以下注入方式,此时是按照byType注入,打印的结果也是“userServiceImpl1”。(ps:byType注入)

@Resource
private UserService userService;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大局观的小老虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值