8

Tôi đã tạo 2 lớp đơn giản. Constructor của một class được chú thích là @Autowired. Nó chấp nhận đối tượng của một lớp khác. Nhưng mã này không thành công.Constructor injection sử dụng Spring annotation @Autowired không hoạt động

Lớp học: - 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; 
    } 

} 

Khi tôi cố gắng để tải ApplicationConext

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

nó mang lại cho lỗi sau: -

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 

Nếu tôi giới thiệu hàm tạo no-arg trong lớp SimpleBean. Nó không đưa ra lỗi. Nhưng điều này không cho tôi đối tượng được đặt trước của SimpleBean (như trong cấu hình XML sử dụng < constructor-arg>). Vì vậy, khi sử dụng chú thích, bắt buộc phải có hàm tạo không có arg không? Cách thích hợp là gì?

+0

Bạn đang cố gắng gọi như 'AnnotationConfigApplicationContext (" com.domain ")' Package? Vui lòng đặt mã hoàn chỉnh của bạn. –

+0

@RaviParekh có, các lớp này nằm trong gói com.domain. Và tôi đang cố gắng gọi ApplicationContext acnxt = new AnnotationConfigApplicationContext ("com.domain"); Nó đã được đề cập. –

Trả lời

20

Từ javadoc của @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. 

Vì vậy, bạn sẽ phải tìm một số cách khác để làm điều đó, không may.

6

Tôi tin rằng bạn đang trộn các chú thích @Configuration@Component. Theo spring docs, @Configuration được sử dụng để tạo ra hạt cà phê sử dụng mã Java (bất kỳ phương pháp chú thích với @Bean tạo một bean, trong khi các lớp học chú thích với @Component sẽ được tự động tạo ra ..

Tôi hy vọng những điều sau đây minh họa điều này:

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

Các lớp học chính sử dụng AnnotationConfigApplicationContext để quét cho cả @Configuration@Component chú thích và tạo ra những hạt cà phê cho phù hợp.

+0

Trong mã của tôi, tôi đã thay đổi chú thích từ @ Configuration thành @ Component trong cả hai lớp SimpleBean và InnerBean. Tôi vẫn nhận được lỗi tương tự.Nó vẫn còn phàn nàn "Không tìm thấy hàm tạo mặc định". –

+0

Tôi đã thử nghiệm mã ví dụ mà tôi đã cung cấp cùng với Spring 3.0.6 và nó in "test123". Bạn đang sử dụng phiên bản mùa xuân nào? Bạn có thể muốn hiển thị thêm cấu hình của mình vì tên lớp 'com.domain.SimpleBean $$ EnhancerByCGLIB $$ 4bc418be. () 'gợi ý rằng có thêm các proxy liên quan. – beny23

+0

Tôi đã thử nghiệm nó bằng cách sử dụng chỉ có 3,0,6 chum mùa xuân. Khi tôi đánh dấu các lớp có thành phần @ thay vì cấu hình @; nó có lỗi tương tự. Chỉ có một phần CGLIB không được tham gia. –

Các vấn đề liên quan