3

簡略化されたコード (私は Spring 3.1.4 を使用しています)。

自動配線したいクラスは次のとおりです。

public class MyCoolClass {

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

    // ...
}

これが私の春の設定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

質問:

  • なぜデフォルトのコンストラクターが必要なのですか? 呼ばれたくありません。
  • クラスで何らかの理由で「@Component」が必要ですか? 私は他の人がこれをしているのを見ます
  • junit テストでこのコードが機能するのはなぜですか (私が知る限り)。(私がそれらをどのように実行しているかを以下に示します。

単体テストを実行するためのスニペットは次のとおりです。

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

2 に答える 2

3

空のコンストラクターがないため、Spring コンストラクターの解決を機能させるには、constructor-args を指定する必要があります...

例えば

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;
    }
}

次のように Bean を定義することで、引数を明示的に指定できます。

<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> 

- - - - - - - - - - - - - - - アップデート - - - - - - - - - - ------------

コンストラクター引数を手動で追加したくない場合は、次を使用して自動配線を試すことができます

<bean name="GreatBean" class="mypackage.MyCoolClass" autowire="constructor" />
于 2013-07-18T22:21:51.457 に答える
2

答え(数時間後)は次を使用することです:

AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);

Bean 定義が読み取られた後、コンテキストが初めてリフレッシュされる前。これにより、XML やクラス定義に触れることなく、必要なもの (コンストラクターの自動配線) が得られます。また、うまくスケーリングされます (将来的には、上記のように XML とクラスを書き続けることができ、何も変更する必要はありません。動作する最後のコードは次のとおりです。

GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new ClassPathResource("config.xml"));
AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx);
ctx.refresh();
于 2013-07-19T00:34:06.967 に答える