@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
相同点:
在Spring中都可以用来注入bean,同时还可以作为注入属性的修饰。在接口只有一个单一实现类时,两个注解的修饰效果是相同的,两者之间可以相互替换,不影响使用。
不同点:
1.@Resource是java的注解,需要导入对应的包才能使用。@Resource有两个属性,分别是name和type。Spring对@Resource注解的name属性解析为bean的名字,type解析为bean的类型。如果指定name,则使用byName的自动注入策略,如果制定type,则使用btType的自动注入策略。同时指定name和type,则从spring中寻找唯一匹配的bean进行装配,找不到则抛出异常。如果既不指定name也不指定type,则自动按照byName进行装配,如果没有匹配,就使用byType进行匹配,没有就抛出异常。
2.@Autowired是spring的注解,是spring2.5版本引进的。只根据type进行注入,不会去匹配name。如果涉及到根据type无法辨别的注入对象,则需要依赖@Qualifier或者@Primary注解一起来修饰。
实战:
首先定义了两个类都实现了Animal接口
public interface Animal {
String features();
}
@Service
public class bird implements Animal {
public String features() {
return String.format("%s can fly","bird");
}
}
@Service
public class dog implements Animal {
public String features() {
return String.format("%s can call",getClass());
}
}
然后定义一个Controller层:
@RestController
@RequestMapping("")
public class AnimalController {
@Autowired
Animal animal;
@RequestMapping("/test")
public String animal(){
return animal.features();
}
}
这里使用的是@Autowired来进行注入,编译运行可以发现报错了。
***************************
APPLICATION FAILED TO START
***************************
Description:
Field animal in com.example.test.AnimalController required a single bean, but 2 were found:
- bird: defined in file [/home/mi/local/Ideaproject/test/target/classes/com/example/test/bird.class]
- dog: defined in file [/home/mi/local/Ideaproject/test/target/classes/com/example/test/dog.class]
报错信息很明显,AnimalCOntroller需要一个bean实例,但是找到了两个。
解决方案:使用@Primary注解,在有多个实现bean时告诉spring首先@Primary修饰的那个;或者使用@Qualifier来标注需要注入的类。
@Service
@Primary()
public class bird implements Animal {
public String features() {
return String.format("%s can fly","bird");
}
}
或者
@RestController
@RequestMapping("")
public class AnimalController {
@Autowired
@Qualifier("bird")
Animal animal;
@RequestMapping("/test")
public String animal(){
return animal.features();
}
}
都可以解决问题。
如果使用@Resource注解,报错信息如下:
No qualifying bean of type 'com.example.test.Animal' available: expected single matching bean but found 2: bird,dog
报错信息是没有找到name为Animal的bean,而按照byType查找则找出了bird和dog两个bean。
解决办法可以在注解括号内加上name = “bird”指定bean的名称,或者使用@Qualifier("bird")来指定。