@Autowired 和 @Resource 的区别是什么?
@Autowired是Spring内置的注解
它默认的注入方式是byType(根据类型进行匹配) , 也就是优先根据接口的类型去注入Bean(接口的实现类) 。
但是 , 如果当一个接口存在很多个实现类的情况下 , byType是无法正确注入对象的 , 因为Spring会同时找到多个满足条件的实现类 , 默认情况根据类型无法选择 。这种情况下 , 注入方式会自动变成byName(根据名称进行匹配) , 这个名称通常为类名(首字母要小写) 。如下:
@Autowired
private UserInfoService userInfoService;
举个例子 , UserInfoService接口有两个实现类 : UserInfoServiceImpl1 和 UserInfoServiceImpl2 , 并且他们都已经呗Spring容器进行管理。则可能会出现以下几种情况:
第一种 :
// 报错: 因为byType会找到两个实现类,但是byName并找不到对应的
@Autowired
private UserInfoService UserInfoServiceImpl;
第二种 :
// 正确注入: 因为byType会找到两个实现类,但是byName可以找到对应的UserInfoServiceImpl1
@Autowired
private UserInfoService UserInfoServiceImpl1;
第三种 :
// 正确注入: @Qualifier 注解来显式指定名称
@Autowired
@Qualifier(value = "UserInfoServiceImpl1")
private UserInfoService UserInfoService;
我们建议使用 @Qualifier 注解来显式指定名称而不是依赖变量的名称 。
@Resource属于 JDK 提供的注解
它的默认注入方式为 byName。如果无法通过名称匹配到对应的 Bean 的话,注入方式会变为byType。
@Resource 有两个比较重要且日常开发常用的属性:name(名称)、type(类型)。
如果仅指定 name 属性则注入方式为byName,如果仅指定type属性则注入方式为byType,如果同时指定name 和type属性(不建议这么做)则注入方式为byType+byName。
第一种 :
// 报错: byName 和 byType 都无法匹配到bean
@Resource
private UserInfoService UserInfoService;
第二种 :
// 正确注入 UserInfoServiceImpl1对象对应的bean
@Resource
private UserInfoService UserInfoServiceImpl1;
第三种 :
// 正确注入 UserInfoServiceImpl1对象对应的bean
@Resource(name = "UserInfoServiceImpl1")
private UserInfoService UserInfoService;
简单总结 :
- 包不同 :
@Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
- 注入方式不同 :
Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
- 多实现类处理方式不同 :
- 当一个接口存在多个实现类的情况下,
@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。