之前在项目中一直使用的@Autowired的注解,发现项目中其他同事也有用@Resource注解。然后想研究一下两者的区别。废话不多说,直接上代码。
先定义一个动物接口:
/**
* 动物接口
*/
public interface Animal {
/**
* 动物玩耍
*/
void play();
/**
* 动物吃东西
*/
void eat();
一、当只有一个实现类:
@Service
public class Dog implements Animal {
@Override
public void play() {
System.err.println("狗玩球球");
}
@Override
public void eat() {
System.err.println("狗啃骨头");
}
测试结果:
(1)使用@Resource注解
@Resource
private Animal animal;
@Test
public void contextLoads() {
animal.eat();
animal.play();
}
(2)使用@Autowired注解
@Autowired
private Animal animal;
@Test
public void contextLoads() {
animal.eat();
animal.play();
}
控制台都输出:
输出结果一样,但是仔细看了,@Resource导入的包为:
javax.annotation.Resource;这个包为JAVA自带的包。
而@Autowired导入的包为:
org.springframework.beans.factory.annotation.Autowired;此包为Spring的包。
看到这,原来是两种不同的注入方式,一个java自带的注入。一个是Spring的注入。
那我再写一个实现类测试一下呢。
二、当有多个实现类的时候
再增加一个实现类:
@Service
public class Cat implements Animal {
@Override
public void play() {
System.out.println("猫玩老鼠");
}
@Override
public void eat() {
System.out.println("猫吃鱼儿");
}
}
@Resource注入:
报错:Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.demo.service.Animal' available: expected single matching bean but found 2: cat,dog
意思是找到了两个实现,不知道注入哪一个,引起报错。
这个时候在@Resource后面添加name属性指定注入的对象就可以了
@Autowired注入
IDEA直接报错了,报错提示是,不唯一的Animal类型,注入失败,从这我们也可以知道@Autowired是按类型进注入的。
在@Autowired加上注解@Qualifier(value ="cat")注入成功。
好了,总结一下:
1.@Resource是按名称进行注入的,属于java自带的。@Autowired是按类型进行注入的,属于Spring。
2.在接口只有一个实现类的时候,两者都可以正常注入, 都可以正常使用。
3.在接口有多个实现类的时候,@Resource可以通过name属性指定注入的实现类。@Autowired需要增加@Qualifier注解指定注入的实现类。