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)的配置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM