Spring

Dependency Injection in Spring Framework

Dependency Injection in Spring Framework – Dependency Injection can be achieved by Spring Framework using XML configuration, pure JAVA based configuration and implicit bean discovery with Autowiring.

Methods to implement Dependency Injection:

  1. Explicit configuration in XML.
  2. Explicit configuration in JAVA.
  3. Implicit bean discovery and Autowiring.

Dependency Injection in Spring Framework using XML

It’s one of the ways to implement dependency injection in which we use XML to define our dependencies.Let ‘s understand it in a bit more detail with the help of below example.

The example of Dependency Injection without Spring, which we have seen in this post, let’s re-write it using spring framework by our 1st method that is “Explicit configuration in XML”.

Download this application–>Download

CellPhone.java


package com.codegeekslab.device;

public interface CellPhone {

public void makeCall(int number);

}

BasicPhone.java


package com.codegeekslab.type;

import com.codegeekslab.device.CellPhone;

public class BasicPhone implements CellPhone {

public void makeCall(int number) {
System.out.println("calling via simcard... " + number);
}

}

SmartPhone.java


package com.codegeekslab.type;

import com.codegeekslab.device.CellPhone;

public class SmartPhone implements CellPhone {

public void makeCall(int number) {
System.out.println("calling via whatsapp..." + number);
}

}

CallingApp.java


package com.codegeekslab.app;

import com.codegeekslab.device.CellPhone;

public class CallingApp {

private CellPhone phone;

// for setter injection
public void setPhone(CellPhone phone) {
this.phone = phone;
}

public CellPhone getPhone() {
return phone;
}

public void dialNumber(int number) {
phone.makeCall(number);
}

}

beans.xml


<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-2.5.xsd">

<bean id="BasicPhone" class="com.codegeekslab.type.BasicPhone" />
<bean id="SmartPhone" class="com.codegeekslab.type.SmartPhone" />
<bean id="CallingApp" class="com.codegeekslab.app.CallingApp">
<property name="phone" ref="BasicPhone" />
</bean>

</beans>

Test.java


package com.codegeekslab.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

import com.codegeekslab.app.CallingApp;

public class Test {

public static void main(String[] args) {
ApplicationContext context = new GenericXmlApplicationContext("beans.xml");
CallingApp callingApp = (CallingApp) context.getBean("CallingApp");
callingApp.dialNumber(1419494494);
}
}

Output


Feb 28, 2017 12:44:04 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Feb 28, 2017 12:44:04 PM org.springframework.context.support.GenericXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericXmlApplicationContext@5e9f23b4: startup date [Tue Feb 28 12:44:04 IST 2017]; root of context hierarchy

calling via simcard... 1419494494

 

If you see there are just 2 changes one is new beans.xml and another is modified Test.java, apart from this everything is same.

To understand these 2 changes that are beans.xml and Test.java we first need to understand two important concepts of spring framework.


1.What is Bean in Spring Framework?

Beans are the java objects that are created and managed by spring container.


2.What is Spring container in Spring Framework?

Spring container is the one who creates and manages the beans.Apart from creating and managing the beans, it is also the place where all spring beans live.


Every Spring application contains beans and container.

Beans are defined in a configuration file which can be an XML or can be a java class if you are using the 2nd and 3rd method to implement dependency injection.The above spring application is an XML based, so we have defined beans in an XML file.

Let’s understand how we have defined beans and spring container in above application example.

We have converted this example of Dependency Injection without spring from our previous post into a spring application by re-writing Test.java and adding one extra file beans.xml.

In this example, we have defined beans in beans.xml and spring container named as ApplicationContext in Test.java.

Let’s first understand beans.xml in detail and then we will move on to Test.java to understand spring container in detail.

In our example of Dependency Injection without spring from our previous post, we had defined our Test.java as below to achieve dependency injection.

CallingApp smartPhone = new CallingApp(); —-1st object
smartPhone.setPhone(new BasicPhone()); ——2nd object and also an setter injection
smartPhone.makeCall(1419494494);

In this class of main we are creating two objects one is of CallingApp and another of BasicPhone and we are performing
Dependency Injection using setter injection by passing object BasicPhone into the setPhone method of CallingApp class.

The number of objects in our application is two, so we would require to create two beans.So now in beans.xml we will define these two objects of CallingApp and BasicPhone and we will also have to perform constructor injection.


<bean id="BasicPhone" class="com.codegeekslab.type.BasicPhone" />
<bean id="SmartPhone" class="com.codegeekslab.type.SmartPhone" />
<bean id="CallingApp" class="com.codegeekslab.app.CallingApp">
<property name="phone" ref="BasicPhone" />
</bean>

Let’s understand the above XML file and how we have defined the beans and setter injection.

To define any object as bean we need to define that object like below ,

<bean id=”BasicPhone” class=”com.codegeekslab.type.BasicPhone”/>

id =”BasicPhone” defines the bean name of BasicPhone class which should be unique and class=”com.codegeekslab.type.BasicPhone” is the name of the class for which we are going to create the bean.

And now we have to define another bean of CallingApp class in which we will inject the BasicPhone bean with setter injection.The syntax is like this

<bean id="CallingApp" class="com.codegeekslab.app.CallingApp">
<property name="phone" ref="BasicPhone" />
</bean>

In the first line we have defined bean creation for CallingApp, And as Our CallingApp requires either object of BasicPhone or Smartphone in the setPhone(CellPhone phone) method of CallingApp Class for setter injection, So in the next line we have defined the syntax for setter injection as <property name=”phone” ref=”BasicPhone” />. As we are passing an object of BasicPhone class, we are mentioning name of BasicPhone bean which is “BasicPhone” in the ref of the property tag.And if you want to inject SmartPhone you can pass bean id of SmartPhone into property tag like below.

<bean id="CallingApp" class="com.codegeekslab.app.CallingApp">
<property name="phone" ref="SmartPhone" />
</bean>

So,

<bean id="CallingApp" class="com.codegeekslab.app.CallingApp">
<property name="phone" ref="BasicPhone" />
</bean>

Is Equivalent of


CallingApp app = new CallingApp();
app.setPhone(new BasicPhone());

The process of injecting a dependency into a another class is also known as “wiring“.

Now we have defined all our beans and wired our beans as required, it’s time to create an object of them by loading this XML
file into spring container “ApplicationContext”.Because beans will only get created once we load this XML using spring container.

Types of Spring Container

In Spring there are two types of container Application context and Bean Factory.

Bean Factory – it is a basic and low-level container thus providing basic support for dependency injection.We won’t discuss much on Bean Factory and mostly advised not to use this container.

Application context – it is a high level, advanced and more powerful than bean factory, apart from supporting Dependency injection supports reading messages from a property file.

Now let’s understand our main class Test which contains ApplicationContext.

Test.java

package com.codegeekslab.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

import com.codegeekslab.app.CallingApp;
public class Test {

public static void main(String[] args) {
ApplicationContext context = new GenericXmlApplicationContext("beans.xml");
CallingApp callingApp = (CallingApp) context.getBean("CallingApp");
callingApp.dialNumber(1419494494);

}
}

Let’s understand what happens in background which when we instantiate an application container and load beans.xml

ApplicationContext context = new GenericXmlApplicationContext("beans.xml");

A particular type of spring container gets instantiated which in this case is GenericXmlApplicationContext(we will learn other types at the end of this page) which is going to manage the beans defined in beans.xml as we are passing this file “beans.xml” into its constructor.

The next step is to get the bean of CallingApp to make the call using dialNumber() method, So to get the bean we
need to call the getBean(“id of the bean”) method and pass the name of bean which we want to get which in the case
is CallingApp and the bean name is “CallingApp”.

The return type of getBean method is java.lang.Object so we need to cast to its actual type before using it.

CallingApp callingApp = (CallingApp) context.getBean("CallingApp");

There is also an another variation where to don’t need to cast but just pass the class name.

CallingApp callingApp = context.getBean("CallingApp",CallingApp.class);

Now we have got the bean or object of CallingApp class we can now call the makeCall method.

callingApp.dialNumber(1419494494);

 

So that was a simple example of dependency injection using spring with XML.

Apart from GenericXmlApplicationContext, there are other types of Application Context as well which are used according to our use-cases.

Types of Application Context

There are several flavors of application context we will discuss now the popular ones and the ones
which we are more likely to use in our projects.

1.ClassPathXmlApplicationContext: it loads the context definitions like beans from one or more XML files located in the classpath.Like in our
example we are using beans.xml as our source of the XML file and loading few beans such as CallingApp.

2.GenericXmlApplicationContext: it’s kind of similar to ClassPathXmlApplicationContext and a better alternative of all application context.

3.FileSystemXmlApplicationContext: if you want to load your XML file from filesystem instead of classpath you can use this FileSystemXmlApplicationContext in which you have to give complete path of XML file like while loading the XML file like below.

ApplicationContext context = new FileSystemXmlApplicationContext(“C:/codegeekslab/beans.xml”);

4.AnnotationConfigApplicationContext:it is used when we are using java configuration classes instead of xml files to define our beans.that we wills ee in a moment.

5.AnnotationConfigWebApplicationContext:it’s used in Spring MVC based web application for loading beans from java configuration classes by using 2nd and 3rd methods.

6.XmlWebApplicationContext: it’s used in Spring MVC based web application for loading beans from xml file .

In our next tutorial, we will learn more about types of dependency injection which we can implement using spring framework.

Leave a Reply

Your email address will not be published. Required fields are marked *