0
votes

I am learning Spring framework (without Spring Boot, in order to understand how it works under the hoods).

I got this beans defined in applicationContext.xml file:

    <bean id="connectionXML" class="com.springLearning.ConnectionXML"/>
    <bean id="xmlBasedDAO" class="com.springLearning.XmlBasedDAO">
        <property name="XMLJdbcConnection" ref="connectionXML" />
    </bean>

This is my DAO class:

    public class XmlBasedDAO {

        private XMLJdbcConnection XMLJdbcConnection;


        public XMLJdbcConnection getXMLJdbcConnection() {
            return XMLJdbcConnection;
        }

        public void setXMLJdbcConnection(XMLJdbcConnection XMLJdbcConnection) {
            this.XMLJdbcConnection = XMLJdbcConnection;
        }
}

This is my ConnectionXML class:

    public class ConnectionXML implements XMLJdbcConnection {
       @Override
       public void connect() {
           System.out.println("Connected");
       }
   }

Which implements this interface :

    public interface XMLJdbcConnection {
        void connect();
    }

Now with a setter injection (as shown above), everything works fine.

But here is the problem: if I switch to a defined constructor injection like so:

    public class XmlBasedDAO {

        private XMLJdbcConnection XMLJdbcConnection;

        public XmlBasedDAO(XMLJdbcConnection XMLJdbcConnection) {
            this.XMLJdbcConnection = XMLJdbcConnection;
        }

        public XMLJdbcConnection getXMLJdbcConnection() {
            return XMLJdbcConnection;
        }
    
}

I got this exception:

Error creating bean with name 'xmlBasedDAO' defined in class path resource [applicationContext.xml]: Instantiation of bean failed;

nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.springLearning.XmlBasedDAO]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.springLearning.XmlBasedDAO.

Why can't I define a constructor in my class with this configuration? Why just a setter injection will work?

I read a lot of questions and the docs too but i did not found an answer for this specific case.

1
And next to the constructor did you also change your xml? - M. Deinum
@M.Deinum No, my xml did'nt change ...why should i change the xml after switching to a constructor injection ? (I am new to this kind of stuff....sorry if my question is obvious) - jossefaz
Which spring version do You use? - Łukasz Olszewski
Because you should also let Spring know you want a constructor based injection instead of properties. - M. Deinum
You should change your xml if you switch to the constructor injection because it is written differently. For setters injection you use propertyName and ref tags to tell spring which dependency you want to inject and when it comes to constructor you should use constructor-arg value. Please look at this link, it is being described nicely there: dzone.com/tutorials/java/spring/… - elec

1 Answers

2
votes

In Spring you can perform DI either by using Constructor Injection or by Setter Injection.

<constructor-arg> tag is used in constructor injection

<property> tag is used in setter injection

You are not changing your xml for constructor injection, you could do this:

<bean id="connectionXML" class="com.springLearning.ConnectionXML"/>
<bean id="xmlBasedDAO" class="com.springLearning.XmlBasedDAO">
    <constructor-arg>
     <ref bean="connectionXML"/> 
    </constructor-arg>  
</bean>

you can check out this tutorial