Friday 3 February 2012

Autowiring in Spring

 So far you have seen how to wire all of your bean's properties using either the <constructor-arg> or the <property> element. In large application, however, all or this explicit wiring can result into lot of xml code. Rather than explicit wiring all of your bean's properties, you can have Spring automatically figure out how to write beans together by setting the autowire property on each <bean> that you want Spring to autowire.

Spring provides four types of autowiring

  • byName
  • byType
  • constructor
  • autodetect


Autowiring byName 
Attempts to find a bean in the container whose name (or Id ) is the same as the name of property being wired. If a matching bean is not found, the property will remain unwired.

Example

DrawingApp.java

public class  DrawingApp {
    public static void main(String[] args) {  
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Triangle triangle = (Triangle) context.getBean("triangle");
        triangle.draw();
    }
}

Triangle.java 

public class Triangle {

    private Point pointA;
    private Point pointB;
    private Point pointC;
   
    public Point getPointA() {
        return pointA;
    }

    public void setPointA(Point pointA) {
        this.pointA = pointA;
    }

    public Point getPointB() {
        return pointB;
    }

    public void setPointB(Point pointB) {
        this.pointB = pointB;
    }

    public Point getPointC() {
        return pointC;
    }

    public void setPointC(Point pointC) {
        this.pointC = pointC;
    }

    public void draw(){

        System.out.println("Point A : ("+pointA.getX()+","+pointA.getY()+")" );
        System.out.println("Point B : ("+pointB.getX()+","+pointB().getY()+")" );
        System.out.println("Point C : ("+pointC.getX()+","+pointC().getY()+")");
    }
}

Point.java

public class Point {
   
    private int x;
    private int y;
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
}




spring.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTDBEAN2.0//EN"  "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="triangle" class="com.example5.Triangle" autowire="byName" />
   
    <bean id="pointA" class="com.example5.Point">
        <property name="x" value="0"/>
        <property name="y" value="0"/>
    </bean>
      <bean id="pointB" class="com.example5.Point">
        <property name="x" value="-20"/>
        <property name="y" value="0"/>
    </bean>
    <bean id="pointC" class="com.example5.Point">
        <property name="x" value="20"/>
        <property name="y" value="0"/>
    </bean>
</beans>

Output : Point A : (0,0)
                 Point B : (-20,0)
                Point C : (20,0)


 Autowiring byType

Attempts to find a single bean in the container whose type matches the type of the property being  wired. If a matching bean is not found, the property will remain unwired. If more than one bean matched found, then UnsatisfiedDependencyException will be thrown.

Example :

DrawingApp.java

public class  DrawingApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Circle circle = (Circle) context.getBean("circle");
        circle.draw();
    }
}

Circle.java

public class Circle{

    private Point center;

    public Point getCenter() {
        return pointA;
    }
    public void setCenter(Point center) {
        this.center = center;
   }
    public void draw(){
        System.out.println(" Center Point is  : ("+center.getX()+","+center.getY()+")" );
    }
}

spring.xml 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="circle" class="com.example5.Triangle" autowire="byType" />
    <bean id="pointA" class="com.example5.Point">
        <property name="x" value="0"/>
        <property name="y" value="0"/>
    </bean>
</beans>

Output : Center Point is (0,0)

Autowiring By Constructor

Tries to match up one or more beans in the container with the parameters of one of the constructors of the bean being wired. In the event of ambiguous beans or constructor, UmsetisfiedDependencyException will be thrown.

Example :

DrawingApp.java  

public class  DrawingApp {
    public static void main(String[] args) {  
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Circle circle = (Circle) context.getBean("circle");        
        circle .draw();
    }
}

Circle.java

public class Circle{

    private Point center;
    public Triangle(Point center){
        this.center = center;
    }
    public void draw(){
        System.out.println("Center Point is ("+center.getX()+","+center.getY()+")" );
    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

    <bean id="circle" class="com.example5.Triangle" autowire="constructor" />
   
    <bean id="pointA" class="com.example5.Point">
        <property name="x" value="0"/>
        <property name="y" value="0"/>
    </bean>
</beans>

Output : Center Point is (0,0)




Thursday 2 February 2012

How to Initialize List, Map,Set and Properties in Spring ?

Let's take an example to understand how to Initialize list in spring.

DrawingApp.java

public class DrawingApp {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Triangle triangle = (Triangle) context.getBean("triangle");
        triangle.draw();
    }
}

Triangle.java

public class Triangle {

    private List<Point> points;
    public List<Point> getPoints() {
        return points;
    }
    public void setPoints(List<Point> points) {
        this.points = points;
    }
  public void draw(){
        System.out.println("Points are ");
        for(Point point : points){
            System.out.println("("+point.getX()+","+point.getY()+")" );
        }
    }


Point.java
 

public class Point {
    private int x;
    private int y;
   
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
   
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="triangle" class="com.example4.Triangle">
        <property name="points">
            <list>
                <ref bean="zeroPoint" />
                <ref bean="point2" />
                <ref bean="point3" />
            </list>
        </property>
    </bean>
    <bean id="zeroPoint" class="com.example4.Point">
        <property name="x" value="0"/>
        <property name="y" value="0"/>
    </bean>
    <bean id="point2" class="com.example4.Point">
        <property name="x" value="-20"/>
        <property name="y" value="0"/>
    </bean>
    <bean id="point3" class="com.example4.Point">
        <property name="x" value="20"/>
        <property name="y" value="0"/>
    </bean>
</beans>

Output :    Points are
                 (0,0)
                 (-20,0)
                 (20,0)

If you want to Initialize MAP then you have to write like this in spring.xml

  <property name="points">
        <map>
            <entry key="Key 1" value="zeroPoint" />
            <entry key="Key 2" value-ref="point2" />
            <entry key="Key 3">
                <bean class="com.example4.Point">
                    <property name="x" value="0" />
                    <property name="y" value="0" />
                </bean>
            </entry>
        </map>
    </property>

If you want to Initialize SET then you have to write like this in spring.xml
 
 <property name= "points">    
      <set>
             <value>1</value>
            
<ref bean="zeroPoint" />
             <bean class="com.example4.Point">
                   <property name="x" value="0" />
                   <property name="y" value="10" />
             </bean>
             <ref bean="point3" />
      </set>
</property>


If you want to Initialize Properties then you have to write like this in spring.xml

<property name="pros">
        <props>
            <prop key="admin">admin@motionwelder.com</prop>
            <prop key="support">support@motionwelder.com</prop>
        </props>
    </property>

Inner Beans

In Spring framework, whenever a bean is used for only one particular property, it’s advise to declare it as an inner bean. And the inner bean is supported both in setter injection ‘property‘ and constructor injection ‘constructor-arg‘.
See a detail example to demonstrate the use of Spring inner bean.

 DrawingApp.java

public class DrawingApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Circle circle = (Circle) context.getBean("circle");
        circle.draw();
    }
}

Circle.java

public class Circle { 
    private Point center;
    public Point getCenter() {
        return center;
    }
    public void setCenter(Point center) {
        this.center = center;
    }
    public void draw() {
        System.out.println("Center is  (" +center.getX()+","+center.getY()+")");
    }
}

Point.java 

public class Point {
    private int x;
    private int y;
   
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
   
}


Often times, you may use ‘ref‘ attribute to reference the “Point” bean into “Circle” bean, person property as following :

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="circle" class="com.example2.Circle">
        <property name="center" ref="centerpoint" />
    </bean>
    <bean id="centerpoint" class="com.example2.Point">
        <property name="x" value="0" />
        <property name="y" value="0" />
    </bean>
</beans>

In general, it’s fine to reference like this, but since the  point bean is only used for Circle bean only, it’s better to declare this Point Bean as an inner bean as following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="circle" class="com.example2.Circle">
        <property name="center">
           <bean class="com.example2.Point">     
                    <property name="x" value="0" />
                    <property name="y" value="0" />
            </bean>
        </property>
    </bean>
</beans>


Output :  Center is (0,0)

ApplicationContextAware and BeanNameAware

 ApplicationContextAware :

Sometimes you need to access your Spring application context from a Spring initialized Bean. For this use case you need to implement the ApplicationContextAware interface. The following code snippets describes the usage:

public class Triangle implements ApplicationContextAware {

    private int a;
    private ApplicationContext context;

    public Point getA() {
        return pointA;
    }
    public void setA(int a) {
        this.a = a;
    }
    public void draw(){
        System.out.println("A= "+a );
    }

    @Override
    public void setApplicationContext(ApplicationContext context)
            throws BeansException {
        this.context = context;
    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
       <bean id="triangle" class="com.example2.Triangle" >
             <property name="a" value="100"></property>
       </bean>
</beans>
 
BeanNameAware :

The Interface BeanNameAware is implemented by beans that help to aware of their bean name in bean factory. The setBeanName method set the name for the bean in the bean factory. In this example you will see how to implement BeanNameAware in your bean class.  


Example : 

DrawingApp.java
public class DrawingApp {

    public static void main(String[] args) {
       
        ApplicationContext context = new ClassPathXmlApplicationContext("
spring.xml");
        Triangle triangle = (Triangle) context.getBean("triangle");
        triangle.draw();
        triangle.setBeanName("triangleBean");
        triangle.showBeanName();
       
    }
}

Triangle.java

public class Triangle implements BeanNameAware {
    int a ;
    String name;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    @Override
    public void setBeanName(String name) {
        this.name= name;
    }
    public void showBeanName() {
        System.out.println("Bean Name is "+name);
    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="triangle" class="com.example2.Triangle">
         <property name="a" value="100" />
    </bean>
</beans> 

Output : Bean Name is triangleBean

BeanFactory and ApplicationContext

BeanFactory:
 
As its name implies, a bean factory is an implementation of the Factory design pattern. That is, it is a class whose responsibility is to create and dispense beans. The BeanFactory is the actual container which instantiates, configures, and manages a number of beans. These beans typically collaborate with one another, and thus have dependencies between themselves. When a bean factory hands out objects, those objects are fully configured, are aware of their collaborating objects, and are ready to use.


BeanFactory is a workhorse that initializes beans and calls their life cycle methods. It should be noted that most life cycle methods only apply to singleton beans. Spring cannot manage prototype (non-singleton) life cycles. This is because, after they’re created, prototypes are handed off to the client and the container loses track of it. For prototypes, Spring is really just a replacement for the “new” operator.


A BeanFactory is represented by the interface org.springframework.beans.factory.BeanFactory, and it is having multiple implementations. The most commonly used simple BeanFactory implementation is org.springframework.beans.factory.xml.XmlBeanFactory. (This should be qualified with the reminder that ApplicationContexts are a subclass of BeanFactory, and most users end up using XML variants of ApplicationContext).


Although for most scenarios, almost all user code managed by the BeanFactory does not have to be aware of the BeanFactory, the BeanFactory does have to be instantiated somehow. This can happen via explicit user code such as:


XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("spring.xml"));


or


XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

ApplicationContext :

A Spring ApplicationContext is a subinterface of BeanFactory. It is somewhat similar to BeanFactory in terms that both define beans,bind them together and make them available on request.In its functioning and ApplicationContext has following advanced features:
  •  Resolving Messages, supporting internationalization(i18n).
  •  Support for an eventing mechanism, allowing application objects to publish events and they can register to be notified of events optionally.
  •  Supports generic loading and access of file resources like image files.
  •  Supports customization of container behavior through automatic recognition of special application-specific or generic, bean definitions.

What is Dependency Injection or Inversion Of Control?

Basic principle behind DI or IOC is that objects define their dependencies. It is the job of container to actually inject those dependencies when it creates  bean. The basic concept of DI is that, you don't need to create your objects but describe how they should be created.. You don't directly connect your components and services together in code but describe which services are needed by which component in a configuration file.

There are two types of dependency Injection :

               1) Setter Injection
               2) Constructor Injection

1) Setter Injection :

The Spring IoC container also supports setter injection, which is the preferred method of dependency injection in Spring. Setter injection uses the setter methods in a class file to garner property names that are configurable in the spring XML config. Let's take one example.


Project Structure :

Example : 

DrawingApp.java

package com.example1;
public class DrawingApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Triangle triangle = (Triangle) context.getBean("triangle");
        triangle.draw();
    }

Triangle.java (Bean)

package com.example1;
public class Triangle {


    private String type;
    private int height;
    public String getType() {
        return type;
    }
    public void setType(String type) {      // Setter Injection(called in order to initialize the value)
        this.type = type;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public void draw(){
        System.out.println("Triangle Drawn :" +getType()+" with Height :" +getHeight());
    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
            <bean id="triangle" class="com.example1.Triangle">
                <property name="type"  value="Equilateral" />
                <property name="height"  value="65" /> 
       </bean>
</beans>
Output :  Equilateral Triangle Drawn with Height 65

      
2) Constructor Injection : 
                                   
As the name implies, using constructor the Spring IOC container will inject the dependencies. The constructor will take arguments based on number of dependencies required. This is one of the drawback using Constructor based DI. You don't have option to reconfigure the dependencies at later point of time, since all the dependencies are resolved only at the time of invoking the constructor. if you don't have requirement to inject all the dependencies, please use Setter Injection technique to obtain the more flexibilty on configuring beans.

Example :
 
DrawingApp.java

package com.example1;
public class DrawingApp {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Triangle triangle = (Triangle) context.getBean("triangle");
        triangle.draw();
    }
}

Triangle.java

package com.example1;
public class Triangle {

    private String type;
    private int height;
   
    public Triangle(String type, int height){
        this.type = type;
        this.height = height;
    }
    public void draw(){
        System.out.println(this.type+" Triangle Drawn with height " +this.height);
    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
      <bean id="triangle" class="com.example1.Triangle">
           <constructor-arg value="Equilateral" />
           <constructor-arg value="65" />
      </bean>  
</beans>

Output :  Equilateral Triangle Drawn with height 65

To execute this examples you need jar files which you can download from http://www.springsource.org/download.