8

2つのシンプルクラスを作成しました。 1つのクラスのコンストラクターに@Autowiredとして注釈が付けられます。別のクラスのオブジェクトを受け入れます。しかし、このコードは失敗します。Springアノテーション@Autowiredを使用したコンストラクタインジェクションは機能しません

クラス: - 1)SimpleBean.java

@Configuration 
public class SimpleBean { 
    InnerBean prop1; 

    public InnerBean getProp1() { 
    return prop1; 
    } 

    public void setProp1(InnerBean prop1) { 
    System.out.println("inside setProp1 input inner's property is " 
     + prop1.getSimpleProp1()); 
    this.prop1 = prop1; 
    } 

    @Autowired(required=true) 
    public SimpleBean(InnerBean prop1) { 
    super(); 
    System.out.println("inside SimpleBean constructor inner's property is " 
     + prop1.getSimpleProp1()); 
    this.prop1 = prop1; 
    } 
} 

2)Inner.java

@Configuration 
public class InnerBean { 
    String simpleProp1; 

    public String getSimpleProp1() { 
    return simpleProp1; 
    } 

    public void setSimpleProp1(String simpleProp1) { 
    this.simpleProp1 = simpleProp1; 
    } 

} 

私はApplicationConext

ApplicationContext acnxt = new AnnotationConfigApplicationContext("com.domain"); 

をロードしようとするとそれは次のエラーを与えます: -

Exception in thread "main" org.springframework.beans.factory.BeanCreationException:   Error creating bean with name 'simpleBean' defined in file [C:\Users\owner\Documents\Java Project\MyWorkSpace\springMVCSecond\WebContent\WEB-INF\classes\com\domain\SimpleBean.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.domain.SimpleBean$$EnhancerByCGLIB$$4bc418be]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.domain.SimpleBean$$EnhancerByCGLIB$$4bc418be.<init>() 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:965) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911) 
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:293) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) 
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:75) 
at com.test.SpringAnnotationTest.main(SpringAnnotationTest.java:12) 
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.domain.SimpleBean$$EnhancerByCGLIB$$4bc418be]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.domain.SimpleBean$$EnhancerByCGLIB$$4bc418be.<init>() 
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:958) 
... 12 more 
Caused by: java.lang.NoSuchMethodException: com.domain.SimpleBean$$EnhancerByCGLIB$$4bc418be.<init>() 
at java.lang.Class.getConstructor0(Unknown Source) 
at java.lang.Class.getDeclaredConstructor(Unknown Source) 
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:65) 
... 13 more 

SimpleBeanクラスに引数なしのコンストラクタを導入するとします。それは間違いを与えません。 しかし、これはSimpleBeanのプリポールされたオブジェクトを与えません(< constructor-arg>を使ったXML設定のように)。 アノテーションを使用する場合、引数なしのコンストラクタを使用することは必須ですか? 適切な方法は何ですか?

+0

あなたは 'AnnotationConfigApplicationContext(" com.domain ")' Packageのようにコールしようとしていますか?完全なコードを入力してください。 –

+0

@RaviParekhはい、これらのクラスはcom.domainパッケージにあります。そして、私はApplicationContextを呼び出そうとしています。acnxt = new AnnotationConfigApplicationContext( "com.domain");それは既に言及された。 –

答えて

20

@Configurationのjavadocのから:

Configuration is meta-annotated as a {@link Component}, therefore Configuration 
classes are candidates for component-scanning and may also take advantage of 
{@link Autowired} at the field and method but not at the constructor level. 

だからあなたは、残念ながら、それを行うためにいくつかの他の方法を見つける必要があります。

6

@Configuration@Component注釈が混在していると思います。 spring docsあたりとして、@Configuration@Componentで注釈を付けたクラスが自動的に作成されているのに対し、(@Beanでアノテート任意の方法は、Beanを作成したJavaコードを使用してBeanを作成するために使用される。..

私は次のようにこれを示し願っています:

InnerBean .javaファイル:

// this bean will be created by Config 
public class InnerBean { 
    String simpleProp1; 

    public String getSimpleProp1() { 
    return simpleProp1; 
    } 

    public void setSimpleProp1(String simpleProp1) { 
    this.simpleProp1 = simpleProp1; 
    } 
} 

SimpleBean.java:

// This bean will be created because of the @Component annotation, 
// using the constructor with the inner bean autowired in 
@Component 
public class SimpleBean { 
    InnerBean prop1; 

    public InnerBean getProp1() { 
    return prop1; 
    } 

    @Autowired(required = true) 
    public SimpleBean(InnerBean prop1) { 
    this.prop1 = prop1; 
    } 
} 

OuterBean.java

// this bean will be created by Config and have the SimpleBean autowired. 
public class OuterBean { 
    SimpleBean simpleBean; 

    @Autowired 
    public void setSimpleBean(SimpleBean simpleBean) { 
    this.simpleBean = simpleBean; 
    } 

    public SimpleBean getSimpleBean() { 
    return simpleBean; 
    } 
} 

Config.java

// this class will create other beans 
@Configuration 
public class Config { 
    @Bean 
    public OuterBean outerBean() { 
    return new OuterBean(); 
    } 

    @Bean 
    public InnerBean innerBean() { 
    InnerBean innerBean = new InnerBean(); 
    innerBean.setSimpleProp1("test123"); 
    return innerBean; 
    } 
} 

Main.java:

public class Main { 
    public static void main(String[] args) { 
    ApplicationContext ctx = new AnnotationConfigApplicationContext("com.acme"); 
    OuterBean outerBean = ctx.getBean("outerBean", OuterBean.class); 
    System.out.println(outerBean.getSimpleBean().getProp1().getSimpleProp1()); 
    } 
} 

メインクラスは両方@Configuration@Component注釈をスキャンし、Beanを作成するAnnotationConfigApplicationContextを使用していますそれに応じて。

+0

私のコードでは、SimpleBeanとInnerBeanの両方のクラスで、@ Configurationから@ Componentへアノテーションを変更しました。それでも私は同じエラーが発生しています。それでも "デフォルトコンストラクタが見つかりません"という文句があります。 –

+0

私はSpring 3.0.6で提供したサンプルコードをテストし、 "test123"を出力します。どのバージョンのスプリングを使用していますか?クラス名が 'com.domain.SimpleBean $$ EnhancerByCGLIB $$ 4bc418be 'であるため、より多くの設定を表示することができます。 ()は、さらにプロキシが関与していることを示しています。 – beny23

+0

私はspring 3.0.6 jarsだけを使ってテストしました。 @ configurationの代わりに@ componentでクラスをマークしたとき、同様のエラーが発生しました。 CGLIB部分のみが関与していませんでした。 –

関連する問題