我的@component出了什么问题?

时间:2013-12-13 08:02:40

标签: java spring

我想要自动装配我的组件,但似乎我无法弄明白。我知道如何使用@Autowired& @Qualifier在我的xml中使用context:annotation-config。但是我如何使用组件做同样的工作呢?我的片段是:

我要注入bean的组件。

@Component
    public class Pianist implements Performer{

       private Instruments instrument;

       @Autowired
       public void makeInstrument(Instruments instrument) {
           this.instrument = instrument;
       }

        @Override
        public void perform() {

            instrument.play();    
        }

我要注入的组件:

    @Component
    public class Piano implements Instruments{

        @Override
        public void play() {
            System.out.println("Piano");
        }  
    }

我的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:p="http://www.springframework.org/schema/p"
       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:component-scan
        base-package = "com.city.lt">
    </context:component-scan>  

</beans>

我的主要成员:

ApplicationContext context = new ClassPathXmlApplicationContext("builder.xml");
    Performer performer = (Performer)context.getBean("Pianist");
    performer.perform();

然后我尝试运行它,我收到此错误:

Could not autowire method: public void com.city.lt.Pianist.makeInstrument(com.city.lt.Instruments);

这有什么问题?感谢

已编辑:stacktrace

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pianist': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.city.lt.Pianist.makeInstrument(com.city.lt.Instruments); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.city.lt.Instruments] is defined: expected single matching bean but found 2: [guitar, piano]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    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:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.city.lt.main.main(main.java:11)

3 个答案:

答案 0 :(得分:2)

你需要setter / constructor /或字段上的@Autowired。 如果您选择了setter,请将其命名为setter

   @Autowired
   public void setInstrument(Instruments instrument) {
       this.instrument = instrument;
   }

创建的所有Bean都以小写字母开头(默认情况下):

Performer performer = (Performer)context.getBean("pianist");

问题是你有2个Instrument的实现。 Spring不知道选择哪一个(因为它真的没有创意而且不关心音乐)

你需要告诉Spring究竟应该使用什么。 Ether通过使用@Primary注释一个或将所有实现连接到Collection或使用您想要作为字段类型连接的实现类,或者使用@Qualifier("piano")和您的自动连接注释。

   @Autowired
   public void makeInstrument(@Qualifier("piano") Instruments instrument) {
       this.instrument = instrument;
   }

答案 1 :(得分:0)

如果您之后不需要“makeInstrument”方法,则这样更容易:

@Component
public class Pianist implements Performer{

   @Autowired
   private Instruments instrument;

    @Override
    public void perform() {

        instrument.play();    
    }
}

答案 2 :(得分:0)

看看堆栈跟踪

No unique bean of type [com.city.lt.Instruments] is defined: expected single matching bean but found 2: [guitar, piano]

您有2个类实现Instruments接口。默认情况下,Spring使用@Autowired时会按类型执行此操作。因为有两个相同类型的bean,它不知道要注入哪个bean。 (这也是你的堆栈跟踪告诉你的)。

要做到这一点,唯一的方法就是使用@Qualifier来指定注入哪一个。