Search This Blog

Saturday 14 April 2012

The autowire-candidate attribue

There may arise a scenario wherein we do not want certain beans to be autowired into the property of other beans. Consider the Simple Car class from an earlier example:
public class CarByName implements ICar {
    private Engine combustEngine;
    private Seating leatherSeating; 
 
    @Override
    public String describe() {        
        return "Car is " + this + ", engine is " + this.getCombustEngine() 
                + " and seating is " + this.getLeatherSeating();
    }
    //setter -getters
}
The xml configuration is
<bean id="carByName" class="com.car.CarByName" autowire="byName"/>
<bean id="combustEngine" class="com.car.Engine" p:name="Combusto" />
<bean id="leatherSeating" class="com.car.Seating" p:color="red" autowire-candidate="false"/>
Attempts to instantiate the bean would throw the exception:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'carAutoDetect' defined in class path resource [autowired-beans.xml]: 
Unsatisfied dependency expressed through constructor argument with index 1 of type [com.car.Seating]: 
: No matching bean of type [com.car.Seating] found for dependency: expected at least 1 bean which 
qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception 
is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type 
[com.car.Seating] found for dependency: expected at least 1 bean which qualifies as autowire candidate 
for this dependency. Dependency annotations: {}
The exception occurred as Spring could not find a Seating bean to autowire. The bean would work fine if we removed the autowire-candidate setting from false. We can use the Seating bean in explicit wiring , but it will not be used for auto-wiring.
Similar is the case when we are using autowire by constructor.
<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" />
<bean id="leatherSeating1" class="com.car.Seating" p:color="red" autowire-candidate="false"/>
In this case the creation of  the above CarByConstructor object, will not throw an exception.
As there are two beans of the same type, Spring Container would not be abke to decide on the wiring and should have thrown an exception.
Bean with id "leatherSeating1" will not be used for any auto-wiring. The code finds a single bean of type Seating and a single bean of type Engine, thus resulting in correct code execution.

No comments:

Post a Comment