1、@Autowired
由Spring提供,只按照byType注入
2、@Resource
由J2EE提供,默认按照byName自动注入。
@Resource有两个重要的属性:name和type。
Spring将@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序:
(1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常;
(2)如果指定了name,则从Spring上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常;
(3)如果指定了type,则从Spring上下文中找到类型匹配的唯一bean进行装配,找不到或找到多个,都抛出异常;
(4)如果既没指定name,也没指定type,则自动按照byName方式进行装配。如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource按类型注入的作用相当于@Autowired,当按照Name注入的作用相当于 @Autowired + @Qualifter。
下面以编程实例说明两者区别
统一接口USB
@Component
public interface USB {
public void outPut();
}
实现类Mouse
@Component("Mouse")
public class Mouse implements USB{
@Override
public void outPut(){
System.out.println("Mouse");
}
}
如果只有一个实现类,那么省事可以只使用@Autowried。
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
@Autowired
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
等价于
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
//这里规定按类型找,默认是按名字
@Resource(type = Mouse.class)
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
等价于
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
//按名字查找,这里的name是Compent里面规定的名字
@Resource(name = "Mouse")
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
三者输出如下
当我们引入多一个实现类时,情况会有所变更。
实现类KeyBoard
@Component("KeyBoard")
public class KeyBoard {
public void outPut() {
System.out.println("KeyBoard");
}
}
如果我们还是按照上面的方式直接使用@Autowried,那么执行起来会报错。
错误如下
这是因为@Autowried是按照实现类来找,但当接口有多个实现类时,那么此时就无法区分到底使用哪个实现类注入。此时可以使用 @Qualifier注解配合使用,@Qualifier可以按照名字指定使用哪个实现类。
代码如下
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
//指定KeyBoard,这个也是根据在Spring容器中的名字查找的,在此处就是@Component中的名字
@Qualifier("KeyBoard")
@Autowired
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
等价于
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
//指定KeyBoard,这个也是根据在Spring容器中的名字查找的,在此处就是@Component中的名字
@Resource(name = "KeyBoard")
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
等价于
@SpringBootTest(classes = Homework4Application.class)
@RunWith(SpringRunner.class)
public class test {
//按类型来找,由于这里指定了类,所以不会像Autowried那样出现异常错误。
@Resource(type = KeyBoard.class)
private USB usb;
@Test
public void test(){
usb.outPut();
}
}
三者输出结果如下



