I am new to Spring. Recently I encountered something weird, I was using @Autowired for Auto Injecting Name, Emotion in Person class(I have a different class for each Name, Emotion, Person). I encountered that the Person constructor was getting invoked even if I have not used @Autowired with it. Can anyone explain to me why this is happening?.
Is it related to the Automatic Invocation of Constructor after Object Creation(Person)? Also why Constructor is invoked before @Autowired Functions? (As u can see in the output)
config.xml
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config /> <bean id = "emotionAngry" class="gd.rf.anuragsaini.autowired.annotation.Emotion"> <property name="name" value="Angry :-O"></property> </bean> <bean id = "nameAnuragSaini" class="gd.rf.anuragsaini.autowired.annotation.Name"> <constructor-arg value="Anurag Saini"></constructor-arg> </bean> <bean id = "person" class="gd.rf.anuragsaini.autowired.annotation.Person"/> </beans>
Emotion.java
package gd.rf.anuragsaini.autowired.annotation; public class Emotion { String name; public void setName(String name) { System.out.println("[EMOTION]:Setting Name of Emotion"); this.name = name; } @Override public String toString() { return "Emotion{" + "name='" + name + ''' + '}'; } }
Name.java
package gd.rf.anuragsaini.autowired.annotation; public class Name { String name; public Name(String name) { System.out.println("[NAME]: Setting Name Bean"); this.name = name; } @Override public String toString() { return "Name{" + "name='" + name + ''' + '}'; } }
Person.java
package gd.rf.anuragsaini.autowired.annotation; import org.springframework.beans.factory.annotation.Autowired; public class Person { Name name; Emotion emotion; @Autowired public void setName(Name name) { System.out.println("[PERSON]: Setting Name of Person"); this.name = name; } @Autowired public void setEmotion(Emotion emotion) { System.out.println("[PERSON]: Setting Emotion of Person"); this.emotion = emotion; } public Person(Name name, Emotion emotion) { System.out.println("[PERSON]: Constructor Setting Person"); this.name = name; this.emotion = emotion; } public String toString() { return "Person{" + "name='" + name + ''' + ", emotion=" + emotion + '}'; } }
Main App.java
package gd.rf.anuragsaini.autowired.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { ApplicationContext IOC = new ClassPathXmlApplicationContext("config.xml"); Person person1 = IOC.getBean("person", Person.class);//No need of Type Casting when class is specified System.out.println(person1); } }
Output
[EMOTION]:Setting Name of Emotion [NAME]: Setting Name Bean [PERSON]: Constructor Setting Person [PERSON]: Setting Name of Person [PERSON]: Setting Emotion of Person Person{name='Name{name='Anurag Saini'}', emotion=Emotion{name='Angry :-O'}}
Advertisement
Answer
You defined a Bean of Person class in your xml file, therefore Spring will create an instance of this class. And the constructor you have defined takes a Name and Emotion both other classes you have an instance of.
So Spring will create a Bean of Person even if you don’t use it with Autowire
.
And it gets invoked before the ‘@Autowire functions’ as you called them because they are methods and you need an instance to call them and the constructor gets called when you create an instance.
I hope I understood your question correct and this answers it.