Friday 3 January 2014

Spring Annotation Based Auto-Wiring


In Spring autowired bean via @Autowired, and it can be applied on setter method, constructor or a field.

See following full example to demonstrate the use of @Autowired.



@Autowired on Setter Methods:

 

Here is the content of Customer.java

package com.mahesh.training.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


public class Customer {

    private Address address;

    public Address getAddress() {
        return address;
    }

   @Autowired
    public void setAddress(Address address) {
        System.out.println("autowired through setter");
        this.address = address;
    }

    @Override
    public String toString() {
        return "Customer [address=" + address + "]";
    }

}

Here is the content of  Address.java




package com.mahesh.training.spring;

public class Address {
   
    private String city;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
   
    @Override
    public String toString() {
        return "Address [city=" + city + "]";
    }

}

Following is the configuration file beans.xml
Include <context:annotation-config /> in beans.xml file to enable annotaions in beans.
 <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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="customer" class="com.mahesh.training.spring.Customer5">
    </bean>

    <bean id="address" class="com.mahesh.training.spring.Address">
        <property name="city" value="Bangalore"></property>
    </bean>

    <bean id="address2" class="com.mahesh.training.spring.Address">
        <property name="city" value="Mumbai"></property>
    </bean>

</beans>
Here is the content for App.java
package clientpack;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mahesh.training.spring.Customer;

public class App {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "beans.xml");
       
        Customer cust = (Customer) context.getBean("customer");
        System.out.println(cust);
       
    }
}
Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:
Output:
autowired through setter
Customer [address=Address [city=Bangalore]]
 

@Autowired on Constructors :

 

Here is the content of Customer.java

package com.mahesh.training.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


public class Customer {

    private Address address;

    @Autowired
    public Customer(Address address ) {
        System.out.println("autowired through construtor");
        this.address = address;
       
    }
 
    public Address getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "Customer [address=" + address + "]";
    }

}



Following is the configuration file beans.xml
Include <context:annotation-config /> in beans.xml file to enable annotaions in beans.
 <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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="customer" class="com.mahesh.training.spring.Customer">
    </bean>

    <bean id="address" class="com.mahesh.training.spring.Address">
        <property name="city" value="Bangalore"></property>
    </bean>

    <bean id="address2" class="com.mahesh.training.spring.Address">
        <property name="city" value="Mumbai"></property>
    </bean>

</beans>
Here is the content for App.java
package clientpack;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mahesh.training.spring.Customer;

public class App {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "beans.xml");
       
        Customer cust = (Customer) context.getBean("customer");
        System.out.println(cust);
       
    }
}
Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:
Output:
 autowired through construtor
Customer [address=Address [city=Bangalore]]

@Autowired on Properties:

Here is the content of Customer.java

package com.mahesh.training.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


public class Customer {

    @Autowired
    private Address address;
 
    public Address getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "Customer [address=" + address + "]";
    }

}


Following is the configuration file beans.xml
Include <context:annotation-config /> in beans.xml file to enable annotaions in beans.
 <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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="customer" class="com.mahesh.training.spring.Customer">
    </bean>

    <bean id="address" class="com.mahesh.training.spring.Address">
        <property name="city" value="Bangalore"></property>
    </bean>

    <bean id="address2" class="com.mahesh.training.spring.Address">
        <property name="city" value="Mumbai"></property>
    </bean>

</beans>
 
Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:
Output:
Customer [address=Address [city=Bangalore]]

Dependency Checking :

@Autowired with (required=false) option

 

By default, the @Autowired will perform the dependency checking to make sure the property has been wired properly. When Spring can’t find a matching bean to wire, it will throw an exception. To fix it, you can disable this checking feature by setting the “required” attribute of @Autowired to false.


package com.mahesh.training.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


public class Customer {

    @Autowired(required=false)
    private Address address;
 
    public Address getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "Customer [address=" + address + "]";
    }

}

In the above example, if the Spring can’t find a matching bean, it will leave the person property unset.

@Qualifier Example :

 

The @Qualifier annotation us used to control which bean should be autowire on a field. For example, bean configuration file with two similar Address beans.

<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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="customer" class="com.mahesh.training.spring.Customer">
    </bean>

    <bean id="address" class="com.mahesh.training.spring.Address">
        <property name="city" value="Bangalore"></property>
    </bean>

    <bean id="address1" class="com.mahesh.training.spring.Address">
        <property name="city" value="Mumbai"></property>
    </bean>

</beans>

Will Spring know which bean should wire?
To fix it, you can use @Qualifier to auto wire a particular bean, for example,

 package com.mahesh.training.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


public class Customer {

    @Autowired
    @Qualifier("address1")  
    private Address address;


    @Override
    public String toString() {
        return "Customer [address=" + address + "]";
    }

}


It means, bean “address1″ is autowired into the Customer’s address property.


No comments:

Post a Comment