java Spring 构造函数 @Autowired 和 @Qualifier 失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17734565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Constructor @Autowired and @Qualifier fails
提问by Cory Kendall
Simplified code (I'm using Spring 3.1.4).
简化代码(我使用的是 Spring 3.1.4)。
Here's a class that I want autowired:
这是我想要自动装配的类:
public class MyCoolClass {
@Autowired
public MyCoolClass(
@Qualifier("CoolBean1") SomeOtherClass1 foo1,
@Qualifier("CoolBean2") SomeOtherClass1 foo2
) {
this.foo1 = foo1;
this.foo2 = foo2;
}
// ...
}
Here is my spring config xml:
这是我的 spring 配置 xml:
<bean name="CoolBean1" class="mypackage.SomeOtherClass1"/>
<bean name="CoolBean2" class="mypackage.SomeOtherClass1"/>
<bean name="GreatBean" class="mypackage.MyCoolClass"/>
And here's how I'm trying to get the bean:
这是我尝试获取豆子的方式:
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new ClassPathResource("config.xml"));
ctx.refresh();
At the point in the refresh call, I encounter this:
在刷新调用时,我遇到了这个:
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.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
Questions:
问题:
- Why do I need a default construtor? I wouldn't want it to be called.
- Do I need "@Component" for some reason on the class? I see others doing this
- Why does this code work (as far as I can tell) through my junit tests? (How I'm running them shown below.
- 为什么我需要一个默认构造函数?我不希望它被称为。
- 出于某种原因,我在课堂上需要“@Component”吗?我看到其他人这样做
- 为什么这段代码可以通过我的 junit 测试工作(据我所知)?(我如何运行它们如下所示。
Here's the snippet for running unit tests:
这是运行单元测试的代码片段:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:config.xml"})
public class MyJunitTest {
//...
}
采纳答案by Cory Kendall
The answer (hours later) is to use:
答案(数小时后)是使用:
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
After the beans definitions have been read, but before the context has been refreshed for the first time. This gets me what I want (constructor autowiring) without having to touch either my XML, or my Class definitions. It will also scale nicely (in the future I can continue writing XML and Classes just as above, and won't need to change anything. The final bit of code which worked was:
在读取 bean 定义之后,但在第一次刷新上下文之前。这让我得到了我想要的(构造函数自动装配),而不必触及我的 XML 或我的类定义。它还可以很好地扩展(将来我可以继续像上面一样编写 XML 和类,并且不需要更改任何内容。最后一段有效的代码是:
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new ClassPathResource("config.xml"));
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
回答by Cristian Meneses
Since you don't have an empty constructor, you must specify the constructor-args, for Spring constructor resolution to work...
由于您没有空构造函数,因此必须指定构造函数参数,以便 Spring 构造函数解析工作...
For example
例如
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;
}
}
you can explicitly specify the args by defining the bean as follows
您可以通过如下定义 bean 来显式指定 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 --------------------------------
- - - - - - - - - - - - - - - 更新 - - - - - - - - - - ------------
If you want to avoid adding constructor-args manually.. you can try autowiring them using
如果你想避免手动添加构造函数参数..你可以尝试使用自动装配它们
<bean name="GreatBean" class="mypackage.MyCoolClass" autowire="constructor" />