Showing posts with label Dependency Injection (DI) In Spring framework With Example. Show all posts
Showing posts with label Dependency Injection (DI) In Spring framework With Example. Show all posts

Why use Dependency Injection in Spring?

What is Dependency Injection:
Originally, dependency injection was commonly referred to by another name inversion of control(IoC). 
In the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application.(Ex: Spring) Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control"

For this new breed of containers the inversion is about how they lookup a plugin implementation. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister.

Based on that revelation, he coined the phrase “dependency injection,” a term that better describes what is going on. Inversion of Control is a generic term and the more specific name for this pattern is Dependency Injection.

Dependency injection is basically giving an object what it needs instead of letting this object get it by itself. It is based on a best practice technique (design pattern). This technique allows a part of application to be changed without causing problems in other areas of the application. A design is inflexible unless it cannot be easily adapted.



Why use Dependency Injection:
        Instead of using Depenedency Injection if we hardcode "new" in our code.

  • What if something changes?
        How do we externalize configuration from Java code, important if things change?

By avoiding use of a custom factory we are reducing extra code to be written in the application

By applying Dependency Injection in your projects, you’ll find that your code will become significantly simpler, easier to understand, and easier to test.

Any nontrivial application is made up of two or more classes that collaborate with each other to perform some business logic. Traditionally,
each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies). This can lead to highly coupled and hard-to-test code. When applying Dependency injection(DI), objects are given their dependencies at creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects. So, DI means an inversion of responsibility with regard to how an object obtains references to collaborating objects.

Software components (Clients), are often a part of a set of collaborating components which depend upon other components (Services) to successfully complete their intended purpose. In many scenarios, they need to know “which” components to communicate with, “where” to locate them, and “how” to communicate with them. When the way such services can be accessed is changed, such changes can potentially require the source of lot of clients to be changed.

One way of structuring the code is to let the clients embed the logic of locating and/or instantiating the services as a part of their usual logic. Another way to structure the code is to have the clients declare their dependency on services, and have some "external" piece of code assume the responsibility of locating and/or instantiating the services and simply supplying the relevant service references to the clients when needed. In the latter method, client code typically is not required to be changed when the way to locate an external dependency changes. This type of implementation is considered to be an implementation of Dependency Injection and the "external" piece of code referred to earlier is likely to be either hand coded or implemented using one of a variety of DI frameworks.

Dependency Injection uses the Hollywood Principle: “Don’t call me, I’ll call you.” In other words, your classes don’t look up or instantiate the classes they depend on. The control is inverted and some form of container sets the dependencies. Using IoC often leads to much cleaner code and provides an excellent way to de-couple dependent classes.



Benefits of Dependency Injection : 
  • Unit testable
  • Dependencies are explicit
  • Consistent
  • Can wire up arbitrarily complicated graphs
  • You don’t need to write plumbing code
  • Pluggability
  • Reduces cost of programming to interfaces to zero

Dependency Injection (DI) In Spring framework With Example


The basic principle behind Dependency Injection (DI) is that objects define their dependencies (that is to say the other objects they work with) only through constructor arguments, arguments to a factory method, or properties which are set on the object instance after it has been constructed or returned from a factory method. Then, it is the job of the container to actually inject those dependencies when it creates the bean. This is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself being in control of instantiating or locating its dependencies on its own using direct construction of classes, or something like the Service Locator pattern.
It becomes evident upon usage that code gets much cleaner when the DI principle is applied, and reaching a higher grade of decoupling is much easier when objects do not look up their dependencies, but are provided with them (and additionally do not even know where the dependencies are located and of what concrete class they are). DI exists in two major variants, namely Constructor Injection and Setter Injection.

Constructor Injection
Constructor-based DI is effected by invoking a constructor with a number of arguments, each representing a dependency. Additionally, calling a static factory method with specific arguments to construct the bean, can be considered almost equivalent, and the rest of this text will consider arguments to a constructor and arguments to a static factory method similarly. Find below an example of a class that could only be dependency injected using constructor injection. Notice that there is nothing special about this class.
public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on a MovieFinder
    private MovieFinder movieFinder;

    // a constructor so that the Spring container can 'inject' a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    
    // business logic that actually 'uses' the injected MovieFinder is omitted...
}
Constructor Argument Resolution
Constructor argument resolution matching occurs using the argument's type. If there is no potential for ambiguity in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments will be supplied to the appropriate constructor when it is being instantiated. Consider the following class:
package x.y;

public class Foo {

    public Foo(Bar bar, Baz baz) {
        // ...
    }
}
There is no potential for ambiguity here (assuming of course that Bar and Baz classes are not related in an inheritance hierarchy). Thus the following configuration will work just fine, and you do not need to specify the constructor argument indexes and / or types explicitly.
<beans>
    <bean name="foo" class="x.y.Foo">
        <constructor-arg>
            <bean class="x.y.Bar"/>
        </constructor-arg>
        <constructor-arg>
            <bean class="x.y.Baz"/>
        </constructor-arg>
    </bean>
</beans>
When another bean is referenced, the type is known, and matching can occur (as was the case with the preceding example). When a simple type is used, such as <value>true<value>, Spring cannot determine the type of the value, and so cannot match by type without help. Consider the following class:
package examples;

public class ExampleBean {

    // No. of years to the calculate the Ultimate Answer
    private int years;

    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}
Constructor Argument Type Matching
The above scenario can use type matching with simple types by explicitly specifying the type of the constructor argument using the'type' attribute. For example:
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg type="int" value="7500000"/>
  <constructor-arg type="java.lang.String" value="42"/>
</bean>
Constructor Argument Index
Constructor arguments can have their index specified explicitly by use of the index attribute. For example:
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>
As well as solving the ambiguity problem of multiple simple values, specifying an index also solves the problem of ambiguity where a constructor may have two arguments of the same type. Note that the index is 0 based.

Setter Injection

Setter-based DI is realized by calling setter methods on your beans after invoking a no-argument constructor or no-argumentstatic factory method to instantiate your bean.
Find below an example of a class that can only be dependency injected using pure setter injection. Note that there is nothing specialabout this class... it is plain old Java.
public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can 'inject' a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually 'uses' the injected MovieFinder is omitted...
}
The BeanFactory supports both of these variants for injecting dependencies into beans it manages. (It in fact also supports injecting setter-based dependencies after some dependencies have already been supplied via the constructor approach.) The configuration for the dependencies comes in the form of a BeanDefinition, which is used together withPropertyEditor instances to know how to convert properties from one format to another. However, most users of Spring will not be dealing with these classes directly (that is programmatically), but rather with an XML definition file which will be converted internally into instances of these classes, and used to load an entire Spring IoC container instance.
Bean dependency resolution generally happens as follows:
  1. The BeanFactory is created and initialized with a configuration which describes all the beans. (Most Spring users use a BeanFactory orApplicationContext implementation that supports XML format configuration files.)
  2. Each bean has dependencies expressed in the form of properties, constructor arguments, or arguments to the static-factory method when that is used instead of a normal constructor. These dependencies will be provided to the bean, when the bean is actually created.
  3. Each property or constructor argument is either an actual definition of the value to set, or a reference to another bean in the container.
  4.  Each property or constructor argument which is a value must be able to be converted from whatever format it was specified in, to the actual type of that property or constructor argument. By default Spring can convert a value supplied in string format to all built-in types, such as int, long,String, boolean, etc.
The Spring container validates the configuration of each bean as the container is created, including the validation that properties which are bean references are actually referring to valid beans. However, the bean properties themselves are not set until the bean is actually created. For those beans that are singleton-scoped and set to be pre-instantiated (such as singleton beans in an ApplicationContext), creation happens at the time that the container is created, but otherwise this is only when the bean is requested. When a bean actually has to be created, this will potentially cause a graph of other beans to be created, as its dependencies and its dependencies' dependencies (and so on) are created and assigned.


Enter your email address to get our daily JOBS & INTERVIEW FAQ's Straight to your Inbox.

Make sure to activate your subscription by clicking on the activation link sent to your email