注解 @Autowired && @Resource区别
@Autowired: 按类型by-type
注入,当遇到接口有多个实现类时,名称不一致时,可以使用@Qualifier
辅助指定需要注入的实现类。
- 可用于构造函数
- 可用于属性
- 可用于setter方法
@Resource: 基于JSR-250. @Resource 首先按名称by-name
注入,然后按类型(如果按名称找到匹配项,则忽略此项);当遇到接口有多个实现类时,名称不一致时,可以使用name
属性辅助指定需要注入的实现类。
- 可用于属性
- 可用于setter方法
测试@Autowired && Resource
通过以下测试可更方便的理解
public interface ComponentParent {
void parent();
}
@Component
public class ComponentChildA implements ComponentParent {
public void parent() {
System.out.println("ComponentChildA");
}
}
@Component
public class ComponentChildB implements ComponentParent {
public void parent() {
System.out.println("ComponentChildB");
}
}
@Component
public class ComponentC {
private String paramA;
private String paramB;
public ComponentC() {
paramA = "1A";
paramB = "1B";
}
public ComponentC(String paramA) {
this.paramA = "11A";
this.paramB = "11B";
}
public ComponentC(String paramA, String paramB) {
this.paramA = "111A";
this.paramB = "111B";
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ComponentC{");
sb.append("paramA='").append(paramA).append('\'');
sb.append(", paramB='").append(paramB).append('\'');
sb.append('}');
return sb.toString();
}
}
测试1 编译运行通过
@RestController
public class TestController1A {
@Autowired
ComponentC componentC;
@Autowired
ComponentParent componentChildA;
@Autowired
ComponentParent componentChildB;
@GetMapping("/test1")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试2 编译不通过
@RestController
public class TestController1B {
@Autowired
ComponentC componentC;
/**
* 变量名与实现类名称不一致
* 无法通过 编译
* Could not autowire. There is more than one bean of 'ComponentParent' type.
* Beans: componentChildA (ComponentChildA.java)
* componentChildB (ComponentChildB.java)
*/
@Autowired
ComponentParent componentChildAA;
/**
* 变量名与实现类名称不一致
* 无法通过 编译
* Could not autowire. There is more than one bean of 'ComponentParent' type.
* Beans: componentChildA (ComponentChildA.java)
* componentChildB (ComponentChildB.java)
*/
@Autowired
ComponentParent componentChildBB;
@GetMapping("/test1B")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test";
}
}
测试3 编译运行通过
@RestController
public class TestController1C {
@Autowired
ComponentC componentC;
/**
* 引入 @Qualifier 指定名称
*/
@Autowired
@Qualifier("componentChildA")
ComponentParent componentChildAA;
/**
* 引入 @Qualifier 指定名称
*/
@Autowired
@Qualifier("componentChildB")
ComponentParent componentChildBB;
@GetMapping("/test1C")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试4 编译运行通过
@RestController
public class TestController2A {
@Resource
ComponentC componentC;
@Resource
ComponentParent componentChildA;
@Resource
ComponentParent componentChildB;
@GetMapping("/test2A")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试5 编译通过运行不通过
@RestController
public class TestController2B {
@Resource
ComponentC componentC;
@Resource
ComponentParent componentChildAA;
@Resource
ComponentParent componentChildBB;
@GetMapping("/test2B")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test";
}
}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testController2B': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'pr.iceworld.fernando.local.component.ComponentParent' available: expected single matching bean but found 2: componentChildA,componentChildB
测试6 编译运行通过
@RestController
public class TestController2C {
@Resource
ComponentC componentC;
@Resource(name = "componentChildA")
ComponentParent componentChildAA;
@Resource(name = "componentChildB")
ComponentParent componentChildBB;
@GetMapping("/test2C")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试7 编译运行通过
@RestController
public class TestController3A {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
public TestController3A(ComponentC componentC, ComponentParent componentChildA, ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildA = componentChildA;
this.componentChildB = componentChildB;
}
@GetMapping("/test3A")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test3A";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试8 编译运行通过
@RestController
public class TestController3B {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
@Autowired
public TestController3B(ComponentC componentC, ComponentParent componentChildA, ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildA = componentChildA;
this.componentChildB = componentChildB;
}
@GetMapping("/test3B")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test3B";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试9 编译不通过
@RestController
public class TestController3C {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
/**
* 编译不通过
* '@Resource' not applicable to constructor
* @param componentC
* @param componentChildA
* @param componentChildB
*/
@Resource
public TestController3C(ComponentC componentC, ComponentParent componentChildA, ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildA = componentChildA;
this.componentChildB = componentChildB;
}
@GetMapping("/test3C")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test3C";
}
}
测试10 编译运行通过
@RestController
public class TestController3D {
ComponentC componentC;
ComponentParent componentChildAA;
ComponentParent componentChildBB;
public TestController3D(ComponentC componentC, ComponentParent componentChildA, ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildAA = componentChildA;
this.componentChildBB = componentChildB;
}
@GetMapping("/test3D")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test3D";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试11 编译运行通过
@RestController
public class TestController3E {
ComponentC componentC;
ComponentParent componentChildAA;
ComponentParent componentChildBB;
@Autowired
public TestController3E(ComponentC componentC, ComponentParent componentChildA, ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildAA = componentChildA;
this.componentChildBB = componentChildB;
}
@GetMapping("/test3E")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test3E";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试12 编译运行通过
@RestController
public class TestController3F {
ComponentC componentC;
ComponentParent componentChildAA;
ComponentParent componentChildBB;
@Autowired
public TestController3F(ComponentC componentC, @Qualifier("componentChildB") ComponentParent componentChildA, @Qualifier("componentChildA") ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildAA = componentChildA;
this.componentChildBB = componentChildB;
}
@GetMapping("/test3F")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test3F";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildB
ComponentChildA
测试13 编译运行通过
@RestController
public class TestController3G {
ComponentC componentC;
ComponentParent componentChildAA;
ComponentParent componentChildBB;
public TestController3G(ComponentC componentC, @Qualifier("componentChildB") ComponentParent componentChildA, @Qualifier("componentChildA") ComponentParent componentChildB) {
this.componentC = componentC;
this.componentChildAA = componentChildA;
this.componentChildBB = componentChildB;
}
@GetMapping("/test3G")
public String test() {
System.out.println(componentC.toString());
componentChildAA.parent();
componentChildBB.parent();
return "test3G";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildB
ComponentChildA
测试14 编译通过运行不通过
@RestController
public class TestController4A {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
@GetMapping("/test4A")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test4A";
}
}
java.lang.NullPointerException: null
at pr.iceworld.fernando.local.controller.TestController4A.test(TestController4A.java:20) ~[classes/:na]
...
测试15 编译通过运行不通过
@RestController
public class TestController4B {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
public void setComponentC(ComponentC componentC) {
this.componentC = componentC;
}
public void setComponentChildA(ComponentParent componentChildA) {
this.componentChildA = componentChildA;
}
public void setComponentChildB(ComponentParent componentChildB) {
this.componentChildB = componentChildB;
}
@GetMapping("/test4B")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test4B";
}
}
java.lang.NullPointerException: null
at pr.iceworld.fernando.local.controller.TestController4B.test(TestController4B.java:31) ~[classes/:na]
...
测试16 编译运行通过
@RestController
public class TestController4C {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
@Resource
public void setComponentC(ComponentC componentC) {
this.componentC = componentC;
}
@Resource
public void setComponentChildA(ComponentParent componentChildA) {
this.componentChildA = componentChildA;
}
@Resource
public void setComponentChildB(ComponentParent componentChildB) {
this.componentChildB = componentChildB;
}
@GetMapping("/test4C")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test4C";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB
测试17 编译运行通过
@RestController
public class TestController4D {
ComponentC componentC;
ComponentParent componentChildA;
ComponentParent componentChildB;
@Autowired
public void setComponentC(ComponentC componentC) {
this.componentC = componentC;
}
@Autowired
public void setComponentChildA(ComponentParent componentChildA) {
this.componentChildA = componentChildA;
}
@Autowired
public void setComponentChildB(ComponentParent componentChildB) {
this.componentChildB = componentChildB;
}
@GetMapping("/test4D")
public String test() {
System.out.println(componentC.toString());
componentChildA.parent();
componentChildB.parent();
return "test4C";
}
}
ComponentC{paramA='1A', paramB='1B'}
ComponentChildA
ComponentChildB