Monday, December 28, 2015

Spring - Explain different modes of auto wiring

The autowiring functionality has five modes which can be used to instruct Spring container to use autowiring for dependency injection:

·         no: This is default setting. Explicit bean reference should be used for wiring.
·         byName: When autowiring byName, the Spring container looks at the properties of the beans on which autowireattribute is set to byName in the XML configuration file. It then tries to match and wire its properties with the beans defined by the same names in the configuration file.
·         byType: When autowiring by datatype, the Spring container looks at the properties of the beans on which autowireattribute is set to byType in the XML configuration file. It then tries to match and wire a property if its type matches with exactly one of the beans name in configuration file. If more than one such beans exist, a fatal exception is thrown.
·         constructor: This mode is similar to byType, but type applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.
·         autodetect: Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire bybyType

Examples

A Customer and Person object for auto wiring demonstration.

package com.mkyong.common;
 
publicclassCustomer
{
        private Person person;
        
        publicCustomer(Person person){
               this.person = person;
        }
        
        publicvoidsetPerson(Person person){
               this.person = person;
        }
        //...
}
 
package com.mkyong.common;
 
public class Person
{
        //...
}

1. Auto-Wiring ‘no’

This is the default mode, you need to wire your bean via ‘ref’ attribute.
        <bean id="customer" class="com.mkyong.common.Customer">
<property name="person" ref="person" />
        </bean>
 
        <bean id="person" class="com.mkyong.common.Person" />

2. Auto-Wiring ‘byName’

Auto-wire a bean by property name. In this case, since the name of “person” bean is same with the name of the “customer” bean’s property (“person”), so, Spring will auto wired it via setter method – “setPerson(Person person)“.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="byName" />
        
        <bean id="person" class="com.mkyong.common.Person" />

3. Auto-Wiring ‘byType’

Auto-wire a bean by property data type. In this case, since the data type of “person” bean is same as the data type of the “customer” bean’s property (Person object), so, Spring will auto wired it via setter method – “setPerson(Person person)“.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="byType" />
        
        <bean id="person" class="com.mkyong.common.Person" />

 4. Auto-Wiring ‘constructor’

Auto-wire a bean by property data type in constructor argument. In this case, since the data type of “person” bean is same as the constructor argument data type in “customer” bean’s property (Person object), so, Spring auto wired it via constructor method – “public Customer(Person person)“.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="constructor" />
        
        <bean id="person" class="com.mkyong.common.Person" />
 

5. Auto-Wiring ‘autodetect’

If a default constructor is found, uses “constructor”; Otherwise, uses “byType”. In this case, since there is a default constructor in “Customer” class, so, Spring auto wired it via constructor method – “public Customer(Person person)“.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="autodetect" />
        
        <bean id="person" class="com.mkyong.common.Person" />
 
 

Spring Autowiring by Name

 
In Spring, “Autowiring by Name” means, if the name of a bean is same as the name of other bean property, auto wire it.

For example, if a “customer” bean exposes an “address” property, Spring will find the “address” bean in current container and wire it automatically. And if no matching found, just do nothing.

You can enable this feature via autowire="byName" like below :
        <!-- customer has a property name "address" -->
        <bean id="customer" class="com.mkyong.common.Customer" autowire="byName" />
        
        <bean id="address" class="com.mkyong.common.Address" >
               <property name="fulladdress" value="Block A 888, CA" />
        </bean>

See a full example of Spring auto wiring by name.

1. Beans

Two beans, customer and address.

package com.mkyong.common;
 
publicclassCustomer
{
        private Address address;
        //...
}

package com.mkyong.common;
 
publicclassAddress
{
        private String fulladdress;
        //...
}

2. Spring Wiring

Normally, you wire the bean explicitly, via ref attribute like this :
        <bean id="customer" class="com.mkyong.common.Customer" >
               <property name="address" ref="address" />
        </bean>
        
        <bean id="address" class="com.mkyong.common.Address" >
               <property name="fulladdress" value="Block A 888, CA" />
        </bean>
Output


Customer [address=Address [fulladdress=Block A 888, CA]]

With autowire by name enabled, you do not need to declares the property tag anymore. As long as the “address” bean is same name as the property of “customer” bean, which is “address”, Spring will wire it automatically.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="byName" />
        
        <bean id="address" class="com.mkyong.common.Address" >
               <property name="fulladdress" value="Block A 888, CA" />
        </bean>

Output

Customer [address=Address [fulladdress=Block A 888, CA]]

See another example, this time, the wiring will failed, caused the bean “addressABC” is not match the property name of bean “customer”.
        <bean id="customer" class="com.mkyong.common.Customer" autowire="byName" />
        
        <bean id="addressABC" class="com.mkyong.common.Address" >
               <property name="fulladdress" value="Block A 888, CA" />
        </bean>

Output


Customer [address=null]

No comments:

Post a Comment