问题
这其实就是@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
详细文档
3.11. 基于注解(Annotation-based)的配置
来源:https://www.cnblogs.com/zhengbin/p/5815291.html