Fork me on GitHub

Spring中@Resource与@Autowired

问题

  这其实就是@Autoware与@Resource没有正确的使用,这个错误是因为wmPoiOplogService这个变量装配方式是@Resource,按照@Resource的按名字查找的方式,并没有找到bean id为wmPoiOplogService的bean所以就报出这个错误。

举个栗子🌰

  

  Bean.java

 1 package service.test;
 2 
 3 
 4 import java.util.List;
 5 
 6 /**
 7  * Created by zhengbin on 16/8/28.
 8  */
 9 public interface Bean {
10     public String sayHello();
11     
12     public List<String> sayHellos();
13 }
Bean.java

  BeanImpl.java

 1 package service.test;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Component;
 5 
 6 import javax.annotation.Resource;
 7 import java.util.ArrayList;
 8 import java.util.LinkedList;
 9 import java.util.List;
10 
11 /**
12  * Created by zhengbin on 16/8/28.
13  */
14 @Component("Bean")
15 public class BeanImpl implements Bean {
16     @Resource
17     private Hello hello2;
18     
19     @Autowired
20     private Hello hello1;
21     
22     @Autowired
23     private List<Hello> hellos;
24     
25     @Override
26     public String sayHello() {
27         return "say " + hello2.say();
28     }
29     
30     @Override
31     public List<String> sayHellos() {
32         List<String> stringList = new ArrayList<String>();
33         for (Hello hello : hellos) {
34             stringList.add(hello.say());
35         }
36         return stringList;
37     }
38 }
BeanImpl.java 

  Hello.java

1 package service.test;
2 
3 /**
4  * Created by zhengbin on 16/8/28.
5  */
6 public interface Hello {
7     public String say();
8 }
Hello.java

  HelloImpl.java

 1 package service.test;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * Created by zhengbin on 16/8/28.
 7  */
 8 @Component("hello1")
 9 public class HelloImpl implements Hello {
10     @Override
11     public String say() {
12         return "Hello1";
13     }
14 }
HelloImpl.java

  HelloImple.java

 1 package service.test;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * Created by zhengbin on 16/8/28.
 7  */
 8 @Component("hello2")
 9 public class HelloImple implements Hello {
10     @Override
11     public String say() {
12         return "Hello2";
13     }
14 }
HelloImple.java

  BeanTest.java

 1 package service.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 /**
 7  * Created by zhengbin on 16/8/28.
 8  */
 9 public class BeanTest {
10     
11     public static void main(String[] args) {
12         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-test.xml");
13         Bean bean = context.getBean("Bean", Bean.class);
14         System.out.println(bean.sayHello());
15         System.out.println(bean.sayHellos());
16     }
17     
18 }
BeanTest.java

  改动BeanImpl.java

17 private Hello hello2;

  改为:

17 private Hello hello1;

  运行结果也由

say Hello2

  变为:

say Hello1

  这说明@Resource是按变量名去找相应的Bean

  而当用第20行的@Autoware方式去执行sayHello()方法时,会报出这个错误:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'Bean': Injection of resource dependencies failed;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [service.test.Hello] is defined: expected single matching bean but found 2: hello1,hello2

  ‘bean of type’说明@Autoware匹配bean的方式是按类型,按类型查找Hello,查找出2个,也就是:‘expected single matching bean but found 2: hello1,hello2’

  所以相应的第23行的hellos与第31行的sayHellos方法就说明了,当按@Autoware匹配切有该类型有多个时,可用List装载

23 private List<Hello> hellos;
31public List<String> sayHellos() {
32   List<String> stringList = new ArrayList<String>();
33      for (Hello hello : hellos) {
34         stringList.add(hello.say());
35       }
36    return stringList;
37 }

@Resource

  @Resource要求提供一个Bean名称的属性(name),如果属性为空,则自动采用标注处的变量名或方法名作为Bean的名称。

    type属性:

    name属性:

@Autoware

  @Autoware默认按类型匹配注入Bean

    required属性:如果希望Spring即使找不到匹配的Bean完成注入也不要抛出异常,那么可以使用@Autoware(required=false)进行标注:

@Autowired(required = false)
private List<Hello> hellos;

  @Qualifier:指定注入Bean的名称

@Autowired
@Qualifier("hello1")
private Hello hello;

   这也就解决了容器中有一个以上匹配的Bean时,报错:expected single matching bean but found 2: hello1,hello2

详细文档

  3.11. 基于注解(Annotation-based)的配置

posted @ 2016-08-28 16:32  郑斌blog  阅读(3960)  评论(0编辑  收藏