2013-07-18 37 views
2

简化代码(我正在使用Spring 3.1.4)。Spring Constructor @Autowired和@Qualifier失败

下面是我想要自动装配类:

public class MyCoolClass { 

    @Autowired 
    public MyCoolClass(
     @Qualifier("CoolBean1") SomeOtherClass1 foo1, 
     @Qualifier("CoolBean2") SomeOtherClass1 foo2 
    ) { 
     this.foo1 = foo1; 
     this.foo2 = foo2; 
    } 

    // ... 
} 

这里是我的Spring配置XML:

<bean name="CoolBean1" class="mypackage.SomeOtherClass1"/> 
<bean name="CoolBean2" class="mypackage.SomeOtherClass1"/> 
<bean name="GreatBean" class="mypackage.MyCoolClass"/> 

而这里的如何,我试图让这个bean:

GenericApplicationContext ctx = new GenericApplicationContext(); 
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx); 
xmlReader.loadBeanDefinitions(new ClassPathResource("config.xml")); 
ctx.refresh(); 

在刷新调用中,我遇到这个问题:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'GreatBean' defined in class path resource [config.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [mypackage.MyCoolClass]: No default constructor found; nested exception is java.lang.NoSuchMethodException: mypackage.MyCoolClass.<init>() 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) 
     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:607) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472) 
     at mypackage.Runner.main(Runner.java:234) 

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [mypackage.MyCoolClass: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.amazon.maxis.security.gbac.AsynchronousFolderAuthorizationManager.<init>() 
     at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990) 
     ... 11 more 

Caused by: java.lang.NoSuchMethodException: mypackage.MyCoolClass.<init>() 
     at java.lang.Class.getConstructor0(Class.java:2800) 
     at java.lang.Class.getDeclaredConstructor(Class.java:2043) 
     at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) 
     ... 12 more 

问题:

  • 为什么我需要一个默认的construtor?我不希望它被调用。
  • 由于某些原因,我需要“@Component”吗?我看到其他人在做这个
  • 为什么这段代码在我的junit测试中工作(据我所知)? (我如何运行它们如下所示

下面是运行单元测试代码片段:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:config.xml"}) 
public class MyJunitTest { 
    //... 
} 
+0

你有一个空的构造? –

+0

@MartinSpa Nope,我没有,我也不想实现它。 –

+0

实际上,也许你不需要。在xml中定义bean时,使用constructor-arg以及参数在你的构造函数中,http://stackoverflow.com/a/10649348/228692 –

回答

2

答案自动装配他们(几小时后)用于:

AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); 

在bean定义有已被阅读,但在第一次刷新语境之前。这使我得到我想要的(构造函数自动装配)而不必触摸我的XML或我的类定义。它也将很好地规模(在未来我可以继续写如上只是XML和类,不需要改变任何事情的工作代码的最后1位是:

GenericApplicationContext ctx = new GenericApplicationContext(); 
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx); 
xmlReader.loadBeanDefinitions(new ClassPathResource("config.xml")); 
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); 
ctx.refresh(); 
+0

不错,您还可以通过在配置文件中添加''来实现。 –

3

既然你没有一个空的构造函数,你必须指定构造函数指定参数时,对春天的构造解析正常工作......

例如

package examples; 

public class ExampleBean { 

    private int years;    //No. of years to the calculate the Ultimate Answer 
    private String ultimateAnswer; //The Answer to Life, the Universe, and Everything 

    public ExampleBean(int years, String ultimateAnswer) { 
     this.years = years; 
     this.ultimateAnswer = ultimateAnswer; 
    } 
} 

你可以明确地指定ARGS通过定义豆如下

<bean id="exampleBean" class="examples.ExampleBean"> 
    <constructor-arg type="int"><value>7500000</value></constructor-arg> 
    <constructor-arg type="java.lang.String"><value>42</value></constructor-arg> 
</bean> 

----------------------------- UPDATE ------------- -------------------

如果你想避免手动添加构造函数ARGS ..你可以尝试使用

<bean name="GreatBean" class="mypackage.MyCoolClass" autowire="constructor" />