8

Ich habe 2 einfache Klassen erstellt. Der Konstruktor einer Klasse ist mit @Autowired gekennzeichnet. Es akzeptiert das Objekt einer anderen Klasse. Aber dieser Code schlägt fehl.Konstruktor Injektion mit Spring Annotation @ Autowired funktioniert nicht

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

} 

Wenn ich versuche, ApplicationConext

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

gibt es folgende Fehler zu laden: -

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 

Wenn ich No-Arg-Konstruktor in SimpleBean-Klasse einführen. Es gibt keinen Fehler. Aber das gibt mir nicht vor-poulated Objekt von SimpleBean (wie in XML-Konfiguration mit < Konstruktor-Arg>). Also, wenn Annotation verwendet wird, ist es notwendig, einen Argon-Konstruktor zu haben? Was ist der richtige Ausweg?

+0

Versuchen Sie, wie 'AnnotationConfigApplicationContext (" com.domain ")' Package aufzurufen? Bitte geben Sie Ihren vollständigen Code ein. –

+0

@RaviParekh Ja, diese Klassen sind im com.domain-Paket. Und ich versuche ApplicationContext aufzurufen acnxt = new AnnotationConfigApplicationContext ("com.domain"); Es wurde bereits erwähnt. –

Antwort

20

Vom javadoc von @Configuration:

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. 

So musst du einen anderen Weg zu finden, es zu tun, leider.

6

Ich glaube, Sie vermischen die und @Component Annotation. Gemäß der spring docs wird @Configuration verwendet Bohnen Code mit Java zu erstellen (alle mit @Bean kommentierten Methoden einer Bean erstellen, während Klassen mit @Component kommentierten automatisch erstellt werden ..

hoffe ich folgendes diesen zeigt:

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

Die Hauptklasse verwendet die AnnotationConfigApplicationContext für beide @Configuration und @Component Anmerkungen zu scannen und die Bohnen erstellen entsprechend.

+0

In meinem Code habe ich die Annotation von @ Configuration in @ Component in den Klassen SimpleBean und InnerBean geändert. Trotzdem bekomme ich denselben Fehler.Es klagt immer noch "Kein Standardkonstruktor gefunden". –

+0

Ich habe den Beispielcode getestet, den ich mit Spring 3.0.6 zur Verfügung gestellt habe und er druckt "test123". Welche Feder verwendest du? Möglicherweise möchten Sie mehr von Ihrer Konfiguration anzeigen, da der Klassenname 'com.domain.SimpleBean $$ EnhancerByCGLIB $$ 4bc418be. () 'schlägt vor, dass weitere Proxies beteiligt sind. – beny23

+0

Ich testete es nur mit Federn 3.0.6 Gläser. Wenn ich Klassen mit @ Komponente anstelle von @ Konfiguration markiert habe; es hatte einen ähnlichen Fehler. Nur CGLIB Teil war nicht beteiligt. –