Home > Enterprise >  Why the constructor is invoked?
Why the constructor is invoked?

Time:06-25

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" >
        <property name="name" value="Angry :-O"></property>
    </bean>

    <bean id = "nameAnuragSaini" >
        <constructor-arg value="Anurag Saini"></constructor-arg>
    </bean>

    <bean id = "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'}}

CodePudding user response:

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.

  • Related