問題
這其實就是@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 }
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 }
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 }
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 }
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 }
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 }
改動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