共同点:
@Resource和@Autowired都可以作为注入属性的修饰,在接口仅有单一实现类时,两个注解的修饰效果相同,可以互相替换,不影响使用。
注意:在只有单一的实现类时,两个注解的作用相同
不同点:
- @Resource是Java自己的注解,@Resource有两个属性是比较重要的,分是name和type;Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
- @Autowired是spring的注解,是spring2.5版本引入的,Autowired只根据type进行注入,不会去匹配name。如果涉及到type无法辨别注入对象时,那需要依赖@Qualifier或@Primary注解一起来修饰。但是如果通过byType找到多个对象时,会通过byName进行比对。
在spring中@Autowired注入规则:
@Autowired默认是按照byType进行注入的,但是当byType方式找到多个符合,则又按照byName方式比对,如果还有多个,则报出异常。
代码演示:
1、只存在单一实现类
public interface TestBiz {
void sendMsg(String msg);
}
@Service("testBizImpl")
public class TestBizImpl implements TestBiz {
@Override
public void sendMsg(String msg) {
System.out.println("TestBizImpl实现类输出信息msg:"+msg);
}
}
单元自测方法
@Autowired
private TestBiz testbiz;
// @Resource
//private TestBiz testbiz;
@Test
public void test() {
testbiz.sendMsg("报警:123213");
}
上述使用@Resource注解和@Autowired注解均能输出结果:
TestBizImpl实现类输出信息msg:报警:123213
存在多个实现类
//新增一个实现类
@Service("bizTestImpl")
public class BizTestImpl implements TestBiz {
@Override
public void sendMsg(String msg) {
System.out.println("BizTestImpl结果输出");
}
}
@Resource
private TestBiz testbiz;
@Test
public void test() {
testbiz.sendMsg("报警:123213");
}
//上述代码运行不成功,因为Resource通过byName进行注入,我们将上述代码换成
@Resource(name="testBizImpl")
private TestBiz testbiz;
@Test
public void test() {
testbiz.sendMsg("报警:123213");
}
即在注解后添加name属性,运行成功
为了不再注解后添加name属性,可以将实例对象名称(了解不多,按照对象实例介绍),也可运行成功,如下:
===================
@Resource
private TestBiz testBizImpl;
@Test
public void test() {
testBizImpl.sendMsg("报警:123213");
}
即将实例名称换为对应的@Service中的名字,运行成功
=====================
如果要使用Autowired注解,因为该注解没有name属性,只能通过这样进行访问,为了演示调用另一个实现类中的方法
@Autowired
private TestBiz bizTestImpl;
@Test
public void test() {
bizTestImpl.sendMsg("报警:123213");
}
输出:BizTestImpl结果输出
TestBiz后面实例化的名称只能是bizTestImpl和testBizImpl,即@Service注解后面的名称;其余均报错