我有这样的类,xml配置文件和错误堆栈跟踪。我不知道为什么@Qualifier不起作用。我看到错误,他甚至做不了什么。
DOG
public class SimpleDog implements Dog {
@Autowired
@Qualifier("small")
private Size size;
private String name;
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void giveSound() {
System.out.println("dog size is : width : (" + size.getWidth() + ") , height : (" + size.getHeight() + ")");
System.out.println("dog's name : " + name);
}
}
TEST CLASS
public class Test2 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-test2.xml");
SimpleDog dog = (SimpleDog) context.getBean("dog");
dog.giveSound();
}
}
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.tests.test2.SimpleDog">
<property name="name" value="Puppy" />
</bean>
<bean id="size1" class="com.tests.test2.Size">
<qualifier value="small"/>
<property name="height" value="2"/>
<property name="width" value="1"/>
</bean>
<bean id="size2" class="com.tests.test2.Size">
<qualifier value="large"/>
<property name="height" value="20"/>
<property name="width" value="10"/>
</bean>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
错误堆栈跟踪
WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dog': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at pl.patrykgryta.test2.Test2.main(Test2.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 18 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 20 more
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dog': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at pl.patrykgryta.test2.Test2.main(Test2.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 18 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
... 20 more
需要帮助
答案 0 :(得分:10)
可能您的ApplicationContext
BeanFactory
配置了默认 AutowireCandidateResolver
(即SimpleAutowireCandidateResolver
)而不是QualifierAnnotationAutowireCandidateResolver
}。
在以前版本的 Spring (4.0之前)中,在创建大多数ApplicationContexts(比较QualifierAnnotationAutowireCandidateResolver
实现)期间设置了AbstractRefreshableApplicationContext.customizeBeanFactory(DefaultListableBeanFactory)
。
目前,AppCtx的QualifierAnnotationAutowireCandidateResolver
可以通过以下方式应用:
org.springframework.beans.factory.annotation.CustomAutowireConfigurer
(请参阅javadoc和postProcessBeanFactory(ConfigurableListableBeanFactory)
方法的实施),例如添加到您的xml:
<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>org.springframework.beans.factory.annotation.Qualifier</value>
</set>
</property>
<context:annotation-config />
(请参阅:AnnotationConfigBeanDefinitionParser.parse(Element,ParserContext)
及相关的)
答案 1 :(得分:4)
@Qualifier用于通过名称或id引用bean。因为它无法找到名称或ID为&#39;小&#39;的xml条目。它尝试按类型进行匹配,它找到了两个Size实例。
以下方法可行:
<bean id="small" class="com.tests.test2.Size">
<property name="height" value="2"/>
<property name="width" value="1"/>
</bean>
虽然看起来您希望将Size实例视为预先配置的bean。如果是这种情况你可以在你的xml文件中声明Dog的实例并引用Size beans ......就像这样:
<bean id="rex" class="com.tests.test2.SimpleDog">
<property name="name" value="Puppy" />
<property name="size" ref="size1"/>
</bean>
答案 2 :(得分:2)
@Qualifier(name =&#34; ..&#34;)注释,并给出我们希望Spring注入的bean的名称
并且您的bean的名称是size1和size2。
所以试试
@Qualifier("size1")
答案 3 :(得分:2)
@Qualifier(“small”)意味着你要找一个名为“small”的bean(bean id =“small”......)@Autowired意味着你要找一个匹配类型的bean。
在某些情况下,将这两种配置结合使用是有意义的。这意味着:寻找一个名为that的bean,如果找不到,那么找一个具有正确类型的bean。这非常强大。
从Spring documentation开始,您可以像使用xml限定符一样声明谁是“小”。但是在他们的例子中有NO id =“...”我不知道定义限定符和id是否有意义。所以我想(我不测试)你可以通过删除部分id =“sizeX”
来修复你的例子答案 4 :(得分:1)
正如您所说的堆栈跟踪
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
Spring无法匹配单个bean来注入,因为他找到了2个可以使用的bean,因此会抛出此异常。
当向BeanFactory请求bean实例时抛出异常 当只有一个时,找到了多个匹配的候选者 期待匹配的豆。
无论如何你以错误的方式使用这个东西,因为没有id="small"
您必须将@Qualifier("small")
更改为@Qualifier("size1")
或@Qualifier("size2")
。
答案 5 :(得分:1)
在Spring 4.x中,您应该使用以下XML架构,以便它可以为您服务:
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"
您应该添加以下标记:
<context:component-scan base-package="com.tests.test2" />
所以下面的XML应该可以解决你的问题(它解决了我的问题:)):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.tests.test2" />
<bean id="dog" class="com.tests.test2.SimpleDog">
<property name="name" value="Puppy" />
</bean>
<bean id="size1" class="com.tests.test2.Size">
<qualifier value="small"/>
<property name="height" value="2"/>
<property name="width" value="1"/>
</bean>
<bean id="size2" class="com.tests.test2.Size">
<qualifier value="large"/>
<property name="height" value="20"/>
<property name="width" value="10"/>
</bean>
</beans>
查看更多here。
答案 6 :(得分:0)
我们的项目中使用了Spring 3.x的struts 1.x.在从spring 3&gt; 4升级的过程中,我们在struts动作中的限定符注释不再起作用。在深入挖掘并比较Spring 3和4之后,终于找到了原因。
reason1:QualifierAnnotationAutowireCandidateResolver不是春季4的默认解析器
在Spring 3中,在我们在应用程序上下文中创建beanfacotry之后,Spring将显式调用:
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
在Spring 4中,在AbstractRefreshableApplicationContext的
中不再调用它protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory)
因此对于父(root)上下文,如果你在config xml中有它,它应该仍然可以工作。但是对于子上下文,默认解析器将变为“SimpleAutowireCandidateResolver”
reason2:在Spring 4的DefaultListableBeanFactory
中尝试确定'isAutowireCandidate()'时,子解析器被传递给父级如果无法做出决定,isAutowireCandidate()会将责任委托给父beanFactory。
在Spring 3中,委托不会将解析器传递给父级,以便父上下文使用自己的解析器来调用isAutowireCandidate()。然而在春季4,它发生了变化。解析器作为参数传递给使用它来调用isAutowireCandidate()的父级。因此,即使父母有一个ContextAnnotationAutowireCandidateResolver,它将QualifierAnnotationAutowireCandidateResolver扩展为其解析器,它仍然无济于事。
如果将@ a5phyx解决方案添加到 子 的应用程序上下文xml中,它应该可以正常工作。
答案 7 :(得分:0)
尝试在beans.xml文件中使用此bean定义:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:context="http://www.springframework.org/schema/context">
<context:annotation-config/>
<!-- define your beans here-->
</beans>