Search This Blog

Saturday, 17 March 2012

Autowiring By Constructor

In this technique, the Spring Container tries to match up beans in the container with the parameters of the constructor arg while creating the bean. Consider the CarByConstructor class:
public class CarByConstructor implements ICar {
    private Engine anyEngine;
    private Seating leatherSeating;

    public CarByConstructor(final Engine anyEngine, final Seating leatherSeating) { 
        System.out.println("In the constructor"); 
        this.anyEngine = anyEngine;
        this.leatherSeating = leatherSeating;
    }
    
    @Override
    public String describe() {        
        return "Car is " + this + ", engine is " + this.anyEngine + " and seating is " + this.leatherSeating;
    }
}
The xml configuration for the same is as below:
<bean id="carByConstructor" class="com.car.CarByConstructor" autowire="constructor"/>
<bean id="combustEngine" class="com.car.Engine" p:name="Combusto" />
<bean id="leatherSeating" class="com.car.Seating" p:color="red" />
I wrote the below code to test the bean:
public static void main(String[] args) {
    final BeanFactory beanFactory  = new XmlBeanFactory(new ClassPathResource("autowired-beans.xml"));
    CarByConstructor carByConstructor = (CarByConstructor) beanFactory.getBean("carByConstructor");
    System.out.println("Bean received is " + carByConstructor.describe());
}
The output indicates that Spring used the constructor to instantiate the bean.
In the constructor
Bean received is Car is com.car.CarByConstructor@12d3205, engine is Engine 
- com.car.Engine@7b6889 and name Simple and seating is seating 
- com.car.Seating@17d5d2a of color red
In this technique it is the type of the argument that is matched. Hence it has the same limitations as autowire by type. If there are multiple beans of the same type, then Spring will not be instantiate the bean.
Also consider the case where the class has multiple constructors and Spring is able to find a match for all of them.
public class CarByConstructor implements ICar {
    private Engine anyEngine;
    private Seating leatherSeating;

    public CarByConstructor(final Engine anyEngine, final Seating leatherSeating) {
        System.out.println("In the constructor");
        this.anyEngine = anyEngine;
        this.leatherSeating = leatherSeating;
    }
    
    public CarByConstructor(final Engine anyEngine) {
        System.out.println("In seatless constructor");
        this.anyEngine = anyEngine;
    }
    
    public CarByConstructor(final Seating leatherSeating) {
        System.out.println("In no engine constructor");
        this.leatherSeating = leatherSeating;
    }
//other methods..
}
The xml configuration is same as before. Spring is capable of creating the bean using any of the above constructors. I executed the above method and the output indicates that Spring used the two parameter constructor.
In the constructor
Bean received is Car is com.car.CarByConstructor@12d3205, engine is Engine 
- com.car.Engine@7b6889 and name Simple and seating is seating 
- com.car.Seating@17d5d2a of color red
I then commented the two parameter constructor and executed the code again.
In seatless constructor
Bean received is Car is com.car.CarByConstructor@12d3205, engine is Engine 
- com.car.Engine@7b6889 and name Simple and seating is null
The Spring Container simply picks up any constructor and creates the bean.

No comments:

Post a Comment