Tuesday, March 20, 2012

@AutoWiring


1.    Introduction:

In the last blog I have explained the Dependency Injection. DI helps in injecting the dependencies using either the <property> or <constructor-arg> elements .And hence whenever there is a new bean defined one needs to go and change the spring configuration file (servlet xml). Just to avoid this, spring offers AutoWiring. AutoWiring helps in reducing configuration overhead by not using the property and constructor arg elements. How?
Let’s first understand the AutoWiring.
Bookish Definition: The Spring container is able to autowire relationships between collaborating beans. This means that it is possible to automatically let Spring resolve collaborators (other beans) for your bean by inspecting the contents of the BeanFactory.
Simple Definition: 
Autowiring let spring container decide which bean to inject into a controller. 
It helps in avoiding the explicit wiring of bean properties.
Example: To display the results from Database, A controller needs a DataSource bean.
Now in Dependency Injection what we do is, we inject the datasoure bean to the controller by setter or constructor dependency injection in the xml configuration file. Autowiring lets Spring to decide how to wire dependency and hence we do not need to explicitly wire bean properties.
Dependency Injection    
 And AutoWiring:

      2. Types of AutoWiring:

  •  byName: Based on the name of a property.
  • byType: Based on a type of class on a setter.
  • constructors: Based on a constructor argument's class types.
  • autodetect : Chooses constructor or byType through introspection of the bean class.
Code examples:
            Class 1:
package com.sk.autowiring;
            public class Player {
                        private Game game;
                        public void setGame(Game game) {
                                    this.game = game;
                        }
                        //Some logic...
}
Class2:
package com.sk.autowiring;
            public class Game {
            private String gameName;
            // Some logic ..
}
Class3:
package com.sk.autowiring;
public class Batsman {
            private String batsmanType;
            //...
}

2.1 ByName:

Autowiring by property name. This option will inspect the container and look for a bean named exactly the same as the property which needs to be autowired. This uses the setter method.
In Dependency Injection, we have done explicit wiring for beans. For ex.
<bean id="player" class="com.sk.autowiring.Player" >
            <property name="game" ref="game" />
</bean>
 <bean id="game" class="com.sk.autowiring.Game" >
            <property name="gameName" value="cricket" />
</bean>
But using autowiring , there is no need to declare the property tag . As long as the “game” bean has same name as the property of “player” bean, which is “game”, spring will wire it automatically.
<bean id="player" class="com.sk.autowiring.Player" autowire="byName"/>
 <bean id="game" class="com.sk.autowiring.Game" >
            <property name="gameName" value="cricket" />
</bean>

2.2 ByType :

When attempting to autowire a property by type, Spring will look for beans whose type is assignable to the property’s type.
            <bean id="player" class="com.sk.autowiring.Player" >
                        <property name="batsman" ref="batsman" />
            </bean>
            <bean id="batsman" class="com.sk.autowiring.Batsman" >
                        <property name="batsmanType" value="opening" />
            </bean>
With autowire by type, properties need not to be set. Spring will find the same data type and wire it automatically.
         <bean id="player" class="com.sk.autowiring.Player" autowire="byType" />
         <bean id="batsman" class="com.sk.autowiring.Batsman" >
                        <property name="batsmanType" value="opening" />
          </bean>
There can be a lot of beans which are of the same type and hence in that case spring will throw exception. There are 2 options using which We can avoid
a)    primary attribute : Bean element’s primary attribute helps in identifying  a primary candidate for autowiring. If its value is true, then that particular bean will be chosen in favor of others.

<bean id="batsman" class="com.sk.autowiring.Batsman” primary=”false”/>
 
b)    autowire-candidate attribute : Bean elements’s is used to identify a preferred autowire candidate among al of them. This attribute actually eliminates beans from considerations of autowiring when the value is set to false.

<bean id="batsman" class="com.sk.autowiring.Batsman” autowire-candidate=”false”/>

2.3 constructor:

 Based on a constructor argument's class types .If the bean is configured using constructor injection, we do not need to define <constructor-arg> elements and let Spring  automatically choose constructor elements from beans in the spring context.
When bean property is wired explicitly:
            <bean id="player" class="com.sk.autowiring.Player" >
                        <constructor-arg>
 <ref bean="batsman" />
</constructor-arg>
            </bean>
            <bean id="batsman" class="com.sk.autowiring.Batsman" >
                        <property name="batsmanType" value="openning" />
            </bean>
With autowire by type, constructor arg elements need not to be set.Spring will find the same data type and wire it automatically.
            <bean id="player" class="com.sk.autowiring.Player" autowire="constructor" />

            <bean id="batsman" class="com.sk.autowiring.Batsman" >
                        <property name="batsmanType" value="openning" />
            </bean>

2.4 autodetect:

 In Spring, "Autowiring by AutoDetect", means chooses "autowire by constructor". If default constructor (argument with any data type), otherwise uses "autowire by type".
<bean id="player" class="com.sk.autowiring.player" autowire="autodetect" />
 <bean id="game" class="com.sk.autowiring.Game" />
           

3.    Autowiring of beans with @Autowired annotations

Autowiring of beans with @Autowired annotations feature started from Spring 2.5 version. @Autowired annotation can be used to auto wire bean on the setter method, constructor or a field. Spring checks the property on which this is being defined and then it will try to perform ‘byType’ autowiring on that property. You don’t need a setter method to use it.  Since Annotation wiring is not turned on by default and hence we need to enable it. 

3.1   Enable autowiring:

               <context:annotation-config />
 
               In the Spring’s context configuration namespace (servlet.xml)
               
   <beans xmlns="http://www.springframework.org/schema/beans"

  ..................... 
                  
             <context:annotation-config />
 
    </beans>
 

3.2 @Autowired property Examples:

1. @Autowired setter method
package com.sk.autowiring;
                        import org.springframework.beans.factory.annotation.Autowired;
                        public class Player {
                                    private Game game;
                                    //Autowiring setter
                                    @Autowired
                                    public void setGame(Game game) {
                                                this.game = game;
                                    }
}
2. @Autowired construtor
package com.sk.autowiring;
import org.springframework.beans.factory.annotation.Autowired;
                        public class Player {
                                    private Game game;
                                    // Autowiring Constructor
                                    @Autowired
                                    public Player(Game game) {
                                                this.game = game;
                                    }
}
3. @Autowired field
package com.sk.autowiring;
                        import org.springframework.beans.factory.annotation.Autowired;
                        public class Player {
                                    //Autowiring field
                                    @Autowired
                                    private Game game;
                        }

4. @Qualifier

There can be a case when more than one bean is defined of the same name or type. In that event, there is no way for @Autowired to choose which one should really be selected. To help @Autowired figure out which bean you want, you can accompany it with Spring's @Qualifier annotation. The @Qualifier annotation used to control which bean should be autowire on a field.
For example, bean configuration file with two similar game beans.
<beans xmlns="http://www.springframework.org/schema/beans"
                            .............   
                        <context:annotation-config />
                        <bean id="Player" class="com.sk.autowiring.Player">
                                                <property name="name" value="Sushant" />
                                    </bean>
                        <bean id="Game1" class="com.sk.autowiring.Game">
                                                <property name="gameName" value="Cricket" />
                                    </bean>
                                    <bean id="Game2" class="com.sk.autowiring.Game">
                                                <property name="gameName" value="Football" />
                                    </bean>
                        </beans>
Now how will Spring decide which bean it should wire? To fix it, you can use  @Qualifier to auto wire a particular bean, for example,
package com.sk.autowiring;
                        import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
                        public class Player {
                                    @Autowired
                                    @Qualifier("Game1")
                                    private Game game;
}
In this case, Game1 is autowired.This is how the Autowiring works.

5.    Pros\Cons of Autowiring

As there are pros and cons of each approach, with this also there are few. Defining everything explicitly in the xml obviously is easier to understand by everybody and even to new people who joins the team at a later stage. But then maintaining an xml file for each and everything will be a big overhead. Annotations are easier to use and maintain.
Now even Spring autowiring also increases the complexity for the servlet xml file and hence better to use the @Autowired annotations.
So which ever approach will be used all are at last Dependency Injection only.




Sunday, March 4, 2012

Dependency Injection


1)       Dependency Injection:

Spring framework has the capability to inject the dependencies to java objects. DI is also known as Inversion of Control (IOC). I have just learnt the Dependency Injection in spring. Although there are lots of articles on this topic but my intention is to let people who are starting to learn spring framework, understand the concepts of DI.
Bookish Definition: Dependency Injection is the dependencies of java objects managed by a container so that Object can concentrate on its functionality rather than for its dependencies. When applying DI, objects are given their dependencies at the creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects.
Simple definition: DI can be simply told as decoupling of work (encouraging the loose coupling).The only thing we need to understand is an object's dependencies should be on interfaces and not on "concrete" objects, when possible. (A concrete object is any object created with the keyword new.) Hence we cannot use new keyword.
Work: Display the names of Indian states.
Class A: Handles the logic part.
Class B: Handles query part from DB.
Class C: Interface
Now Class A does not bother how Class B got the results whether it got it by doing simple query or by writing stored procedures or PL\SQL, what it needs is query results. It will take that results through the interface (Class C) and display the names of the Indian states.
This is somewhat similar to the Hollywood Principle: "Don't call us, we'll call you”. i.e. You implement the interfaces, you get registered. You get called when the time is right.
I don’t want you to confuse further as it’s easy to understand the topic with the help of an example.
Code example:
In the below example, what we are going to do is to find it out which Object Relational Mapping we are using in the code. We will create an Interface, one main class, two different Orm techniques class and then a service class. We will inject the ORM through the controller bean xml and displayOrm method which will display the Orm tool being used.

<pre class="brush: js">
<div id="tweets">
                Orm.java
----------------
package com.sk;
 public interface Orm {
                                public String getOrmName();
}
               
</div>
</pre>

                          
The IBatis and Hibernate class implements Orm interface and getOrmName method.

<pre class="brush: js">
             <div id="tweets">
IBatis.java
----------------
package com.sk;
public class IBatis implements Orm {
                                @Override
                                public String getOrmName() {
                                                return "I'm using iBatis";
                                }
}

Hibernate.java
-------------------
package com.sk;
public class Hibernate implements Orm {
                @Override
                public String getOrmName() {
                                return "I'm using Hibernate";
                }
}

</div>
            </pre>


We have a OrmService class that tells the developer which Object Relational mapping is being used. The OrmService class holds reference to the Orm.

<pre class="brush: js">
 <div id="tweets">
OrmService.java
---------------------
package com.sk;
public class OrmService {
                private Orm orm = new Hibernate();
                public void displayOrm(){
                                System.out.println(orm.getOrmName());
                }
}
</div>
</pre>

At last we will create OrmTool class which will display the Object Relational mapping is being used.

<pre class="brush: js">
 <div id="tweets"> 
OrmTool.java
-------------------
package com.sk;
public class OrmTool {
                public static void main(String[] args) {
                                OrmService ormService = new OrmService();
                                ormService.displayOrm();
                }
}
</div>
</pre>
As you can see it is pretty simple, here we create an instance of the OrmService class and call the displayOrm() method. This method will display the ORM being used.
Let's have a look at the class diagram of this example. The green arrows indicate generalization and the blue arrow indicates association.



 















As you can see this architecture is tightly coupled. We create an instance of the Orm in the OrmService class in the following way to display Hibernate.

 <pre class="brush: js">
<div id="tweets">
private Orm orm = new Hibernate();
</div>
</pre>
To make our Orm display iBatis we need to make modifications to the OrmService class like this.

<pre class="brush: js">
<div id="tweets">
private Orm orm = new IBatis();
</div>
</pre>

So it is tightly coupled. Now let’s see how we can avoid this by using the Dependency Injection design pattern. The spring framework provides powerful container to manage the components. The container will inject the required dependencies. We can inject the dependencies using the setter or constructor injection (this is explained in the later section).
Here we will see how we can do this using the setter injection.

 <pre class="brush: js">
<div id="tweets">
OrmService.java
---------------------
package com.sk;
public class OrmService {
                Orm orm;
                public void setOrm(Orm orm) {
                                this.orm = orm;
                }
                public void displayOrm(){
                                System.out.println(orm.getOrmName());
                }
}

</div>
</pre>

The value for the Orm will be set using the setOrm() method. The Orm object is never instantiated in the OrmService class, but still we access it. Usually this will throw a NullPointerException, but here the containers will instantiate the object for us, so it works fine.
After making all the changes, the class diagram of the example look like this. 




 















The container comes into picture and it helps in injecting the dependencies. The bean configuration is done in the Controller-beans.xml file.

<pre class="brush: js">
<div id="tweets">
Controller-beans.xml
-------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation=" http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-   beans.xsd">
                <bean id="hibernate" class="com.sk.Hibernate"></bean>
                <bean id="iBatis" class="com.sk.IBatis"></bean>
                <bean id="ormService" class="com.sk.OrmService">
                                <property name="orm">
                                                <ref local="hibernate"/>
                                </property>
                </bean>
</beans>

</div>
                 </pre>

We define each bean using the bean tag. The id attribute of the bean tag gives a logical name to the bean and the class attribute represents the actual bean class. The property tag is used to refer the property of the bean. To inject a bean using the setter injection you need to use the ref tag.
Here a reference of Hibernate is injected to the Orm bean. Now when we want to change the ORM to IBatis, the only change we need to do is, to change the bean reference in the ref tag.

<pre class="brush: js">
<div id="tweets">
<bean id="ormService" class="com.sk.OrmService">
                <property name="orm">
                                <ref local="iBatis"/>
                </property>
</bean>

</div>
                 </pre>

2) Types of DI

2.1 Constructor Injection

2.2 Setter Injection

       2.1   Constructor Injection :
    Constructor-based DI is affected by invoking a constructor with a number of arguments, each     representing a dependency.
        <pre class="brush: js">
        <div id="tweets">
a)      Through XML
<bean id="ormService" class="com.sk.OrmService">
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg type="java.lang.String" value="42"/>
</bean

b)      Through Java config :
public class OrmService {

    // the OrmService has a dependency on a Orm
    private Orm orm;

    // a constructor so that the Spring container can 'inject' a Orm
    public OrmService (Orm orm) {
        this. orm = orm;
    }
    // business logic that actually 'uses' the injected Orm is omitted...
           
           </div>
           </pre>

     2.2   Setter Injection
Setter-based DI is realized by calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.

            <pre class="brush: js">
            <div id="tweets"> 
a)      Through XML :
<bean id="ormService" class="com.sk.OrmService">
    <property name="name" value="sk"/>
</bean> 
b)      Through Java config
public class OrmService {

    // the OrmService has a dependency on the Orm
    private Orm orm;

    // a setter method so that the Spring container can 'inject' a Orm
    public void setOrm(Orm orm) {
                                this.orm = orm;
                }

    // business logic that actually 'uses' the injected Orm is omitted...
}

</div>
                </pre>

3. XML or Java Configuration

                The wiring up of the dependencies with the objects can be done using Java code and XML both. Some people prefer java code and some prefer xml configuration. I think it is a simpler to work with Java code. But then for beginners and business people, xml is better as it is easily configurable. This thought is divided and may be in some other article I will try to cover it.