@Autowired 与 @Resource
@Autowired
属于 Spring 内置的注解,默认的注入方式为byType
(根据类型进行匹配),也就是说会优先根据接口类型去匹配并注入 Bean (接口的实现类)。如果一个接口存在多个实现类,那么此时byType
方式注入就会报错,无法注入。此时@Autowired
会转换为以byName
的形式去注入Bean。
举个例子:
public interface SmsService{
void sendSms();
}
@Service
public class SmsServiceImpl1 implements SmsService{
@Override
public void sendSms(){
System.out.println("我是Sms实现1");
}
}
@Service
public class SmsServiceImpl2 implements SmsService{
@Override
public void sendSms(){
System.out.println("我是Sms实现2");
}
}
@RestController
pubic class SmsControllerTest{
// 报错,因为两个实现类,先按byType方式不能唯一确定
// 再按byName形式去找smsService这个名称的Bean也找不到
@Autowired
private SmsService smsService;
}
// 不报错,在byType方式找不到,按byName方式找到了名称为smsServiceImpl1的Bean,此种不推荐
@Autowired
private SmsService smsServiceImpl1;
// 不报错,使用@Qualifier注解指定一个确定的Bean
@Autowired
@Qualifier(value = "smsServiceImpl1")
private SmsService smsService;
@Resource
属于 JDK 提供的注解,默认注入方式为 byName
。如果无法通过名称匹配到对应的 Bean 的话,注入方式会变为byType
,同样拿上面的列子进行举例:
@RestController
pubic class SmsControllerTest{
// 报错,先按byName方式找smsService这个名称的Bean也找不到
// 再按byType形式,因为两个实现类,所以也不能确定
@Resource
private SmsService smsService;
}
// 不报错,默认byName直接就能找到
@Resource
private SmsService smsServiceImpl1;
// 不报错,推荐此种
@Resource(name = "smsServiceImpl1")
private SmsService smsService;
// 报错,byType不唯一确定
@Resource(type = SmsService.class)
private SmsService smsService;
// 不报错,byType唯一确定
@Resource(type = smsServiceImpl1.class)
private SmsService smsService;
// 不报错,但不推荐此种
@Resource(name = "smsServiceImpl1", type = SmsService.class)
private SmsService smsService;
总结
@Autowired
是 Spring 提供的注解,@Resource
是 JDK 提供的注解。@Autowired
默认的注入方式为byType
(根据类型进行匹配),``@Resource默认注入方式为
byName`(根据名称进行匹配)。- 当一个接口存在多个实现类的情况下,
@Autowired
和@Resource
都需要通过名称才能正确匹配到对应的 Bean。@Autowired
可以通过@Qualifier
注解来显式指定名称,@Resource
可以通过 name 属性来显式指定名称