How to use @Autowired on a field whose constructor need argument?
if the class RelationalDataSource has default constructor, the @Autowired function properly as follow
Class CustomerService
Interface DataSourceCode:package com.cybelink.ioc; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; /** * * This class uses the DataSource to load Customer data */ @Component public class CustomerService { @Autowired // can switch between relationDataSource or xmlDataSource @Qualifier("relationalDataSource") //@Qualifier("xmlDataSource") private DataSource dataSource; private Customer customer; public static void main(String[] args){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); // don't create the customerService using new, should use spring method to make // customerService a spring managed bean!! //CustomerService customerService = new CustomerService(); CustomerService customerService = (CustomerService)ctx.getBean("customerService"); customerService.method1(); } public void method1(){ if (dataSource == null) System.out.println("dataSource == null"); customer=(Customer)dataSource.retrieveObject(); System.out.println(getCustomerName()); } public CustomerService() { super(); System.out.println("CustomerService Constructor is called"); } // unrelated code here }
Class implement interface DataSourceCode:package com.cybelink.ioc; /** * * Interface that must be implemented by all types of DataSource */ public interface DataSource { public Object retrieveObject(); public void setDataSourceName(String name); public String getDataSourceName(); public void storeObject(Object object); }
the applicationContext.xml is as followCode:package com.cybelink.ioc; import org.springframework.stereotype.Component; /** * * This class will be used to load the Customer from a Relational Database. */ @Component("relationalDataSource") public class RelationalDataSource implements DataSource { private String name; public RelationalDataSource() { super(); } /** * Using the DataSource retrieve data for Customer and build a * Customer object to return it to the caller */ public Object retrieveObject() { //get data for Customer object from DB and create a //Customer object return new Customer("Relational",10); } /** * Set the DataSource name */ public void setDataSourceName(String name) { this.name=name; } /** * Return the name of the DataSource */ public String getDataSourceName() { return name; } /** * Store Customer into relatioanl DB */ public void storeObject(Object object) { //store the customer data into Relatioanl DB } }
but if I change the no-args constructor of relationalDataSource toHTML Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- ========================= GENERAL DEFINITIONS ========================= --> <context:annotation-config/> <!-- To allow autodetect and register of beans under com.cybelink.ioc package --> <context:component-scan base-package="com" /> <!-- Velocity Engine for email template --> <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="velocityProperties"> <value> input.encoding=UTF-8 resource.loader=class class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader </value> </property> </bean> </beans>
error occur asCode:public RelationalDataSource(int a) { super(); }
Code:Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerService': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cybelink.ioc.DataSource com.cybelink.ioc.CustomerService.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'relationalDataSource' defined in file [C:\workspace\workspace1\Test\bin\com\cybelink\ioc\RelationalDataSource.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.cybelink.ioc.RelationalDataSource]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.cybelink.ioc.RelationalDataSource.<init>()


Reply With Quote
