@AutoWired和@Resource注解的区别
参考网址1:https://blog.csdn.net/weixin_40423597/article/details/80643990
参考网址2:https://www.zhihu.com/question/39356740
两者的基本认识
1、@Autowired注解是Spring自己定义的注解 (Spring团队)
2、Spring框架还去实现了JSR-250(sun/oracle)规范定义的注解@Resource、@PostConstruct以及@PreDestroy。
在某种情况下:Spring实现的@Resource的作用相当于@Autowired
两者的区别
1、只不过@Autowired按byType自动注入、而@Resource默认按 byName自动注入罢了
@Resource
1、@Resource有两个属性是比较重要的,分是name和type,
2、Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,如下
@Resource(name="xxxxServiceImpl")
private UserService userService;
// 源码分析
if(name == 'userServiceImpl'){
return beanfacotry.getBean("userServiceImpl")
}
3、而使用type属性时则使用byType自动注入策略。
@Resource(type=UserServiceImpl.class)
private UserService userService;
// 源码分析
if(type == UserServiceImpl.class){
return beanfacotry.getBean(UserServiceImpl.class)
}
4、如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource //等价于 @Resource(name="xxxxServiceImpl")
private UserService userService;
// 源码分析
if(name == 'userServiceImpl'){
return beanfacotry.getBean("userServiceImpl")
}
5、如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
@Resource(name="xxxx",type=UserServiceImpl.class)
private UserService userService;
// 源码分析
if(name == 'userServiceImpl' && type == UserServiceImpl.class){
return beanfacotry.getBean("userServiceImpl")
}
总结:
1:默认情况 @Resource是根据byname匹配,如果一个接口在开发只有一个实现类,会自动把唯一的实现赋值给接口进行是实例化。这个时候这两者是等价的。
2: 如果@Resource指定的name就必须和sprignioc中的map的key名字要一摸一样。默认情况下,是使用类名首字母小写进行一定,否则报错
3: 如果@Resource指定的type,就必须是当前被注入的类的子类或者当前类,否则报错
4: 如果@Resource指定的type也指定了name,一种双重机制,只有有一个条件不满足就报错。
@Autowired
1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、@Autowired:默认按类型装配(这个注解是属业spring的)
@Autowired(type=UserServiceImpl.class)
private UserService userService;
// 源码分析
if(type == UserServiceImpl.class){
return beanfacotry.getBean(UserServiceImpl.class)
}
3、默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,
如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
@Autowired(required=false)
private UserService userService;
总结:
1: @Autowired默认是根据bytype来匹配,如果一个接口在开发只有一个实现类,会自动把唯一的实现赋值给接口进行是实例化。这个时候这两者是等价的。
2:@Autowired如果找不到子类,就报错NoBeanDefinitionException异常,如果要解决这个异常,在注解上增加required = false即可,但是这个接口或者类是不会被实例化,也就null
这里这个对象在掉用方法的时候就会出现nullponitexception异常。