这里不允许使用元素:对于IntelliJ中的spring bean定义中的限定符

时间:2013-11-17 00:07:11

标签: spring intellij-idea javabeans autowired

这是文件,我正在尝试以下示例: http://simplespringtutorial.com/annotations.html

<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config />

<bean id="foo" class="annotation.Foo">
    <property name="name" value="Daniel"></property>
</bean>
<bean id="anotherFoo" class="annotation.Foo">
   <qualifier value="secondaryFoo"></qualifier>
    <property name="name" value="Shirley"></property>

</bean>
<bean id="bar" class="annotation.Bar" />
</beans>

这是Bar类     import javax.annotation.Resource;     import org.springframework.beans.factory.annotation.Autowired;     import org.springframework.beans.factory.annotation.Qualifier;

public class Bar {
@Autowired
@Qualifier(value="anotherFoo")
private Foo foo;

@Resource(name="foo")
private Foo foo2;

public void setFoo(Foo foo) {
    this.foo = foo;
}
public void  printFooName(){
    System.out.println(foo.getName());
 //   System.out.println(foo2.getName());
}
}

这是加载xml文件的测试栏

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFooBar {

public static void main(String[] args) throws InterruptedException {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
            "test2.xml");
    Bar bar = applicationContext.getBean("bar", Bar.class);
    bar.printFooName();
    System.out.println(bar.toString());
    /*
     * if a single definition of a class type exists, then u can get the
     * instance by this way also. No need to specify Id
     */
    Foo foo = applicationContext.getBean(Foo.class);
    System.out.println(foo.getName());
}

}

当我运行应用程序时,以下是堆栈跟踪:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bar': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private annotation.Foo annotation.Bar.foo; nested exception is     org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [annotation.Foo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=anotherFoo)}
at   org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at annotation.TestFooBar.main(TestFooBar.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private annotation.Foo annotation.Bar.foo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [annotation.Foo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=anotherFoo)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
... 18 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [annotation.Foo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=anotherFoo)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
... 20 more

1 个答案:

答案 0 :(得分:1)

感谢您提供额外的详细信息,并不是很明显您想要做什么。

@Qualifier注释不应与@Resource使用相同的方式。指定元数据<qualifier>元素时,将覆盖解析@Qualifier时将使用的标识符。在这种情况下,<qualifier>标识符"secondaryFoo"会替换<bean>标识符"anotherFoo"。如果您将声明更改为

@Autowired
@Qualifier(value = "secondaryFoo")
private Foo foo;

它将正确自动装配。但是,您仍然可以使用

Foo anotherFoo = (Foo) applicationContext.getBean("anotherFoo");

通过<bean> id获取"anotherFoo"。虽然这会失败

Foo anotherFoo = (Foo) applicationContext.getBean("secondaryFoo");

如果您正在寻找基于唯一ID的自动装配方式,则应使用@Resourcedocumentation州:

  

如果您打算按名称表达注释驱动的注入,请不要   主要使用@Autowired,即使技术上能够引用   通过@Qualifier值获取bean名称。相反,使用JSR-250   @Resource注释,在语义上定义为标识a   特定目标组件的唯一名称,具有声明的类型   与匹配过程无关。