Spring mvc integration with prometheus Example

In this article ,we will see how we can monitor spring MVC applications using prometheus tool . You wont get much documentation for this setup on web. Prometheus is mostly configured with spring boot easily. But in order to configure it with spring MVC based application , it requires some additional configurations –

Prometheus

Prometheus is a time-series monitoring application written in Go. It can run on a server, in a docker container, or as part of a Kubernetes cluster (or something similar). Prometheus collects, stores, and visualizes time-series data so that you can monitor your systems. You can tell Prometheus exactly where to find metrics by configuring a list of “scrape jobs”. Applications that are being monitored can provide metrics endpoints to Prometheus using any one of the many client libraries available; additionally, separate exporters can gather metrics from applications to make them available in Prometheus. Metrics get stored locally for 15 days, by default, and any Prometheus server can scrape another one for data. Additionally, remote storage is another option for Prometheus data – provided there is a reliable remote storage endpoint.

Benefits:

  • The option of “service discovery” allows Prometheus to keep track of all current endpoints effortlessly.
  • Outages are quickly detected .
  • The PromQL query language is incredibly flexible and Turing-complete.
  • There’s also a very low load on the services monitored (metrics get stored in memory as they get generated), allowing fewer resources to get used.
  • Additionally, Prometheus users can control traffic volumes, access metrics in the browser, and allow for easy reconfiguration.

Step 1 : Spring MVC application pom.xml configuration

Below prometheus dependencies are required in pom.xml for project –

<prometheus.version>0.6.0</prometheus.version>
<dependency>
    <groupid>io.prometheus</groupid>
    <artifactid>simpleclient</artifactid>
    <version>${prometheus.version}</version>
</dependency>
<!-- Hotspot JVM metrics-->
<dependency>
    <groupid>io.prometheus</groupid>
    <artifactid>simpleclient_hotspot</artifactid>
    <version>${prometheus.version}</version>
</dependency>
<!-- Exposition servlet-->
<dependency>
    <groupid>io.prometheus</groupid>
    <artifactid>simpleclient_servlet</artifactid>
    <version>${prometheus.version}</version>
</dependency>
<!-- Pushgateway exposition-->
<dependency>
    <groupid>io.prometheus</groupid>
    <artifactid>simpleclient_pushgateway</artifactid>
    <version>${prometheus.version}</version>
</dependency>
<dependency>
    <groupid>io.prometheus</groupid>
    <artifactid>simpleclient_spring_web</artifactid>
    <version>${prometheus.version}</version>
</dependency>
<dependency>
    <groupid>com.fasterxml.jackson.core</groupid>
    <artifactid>jackson-core</artifactid>
    <version>2.5.2</version>
</dependency>

Step 2 : Spring MVC application web.xml configuration

We need configure MetricsServlet to capture the metrics of our spring mvc application as below –

<servlet>
    <servlet-name>PrometheusServlet</servlet-name>
    <servlet-class>io.prometheus.client.exporter.MetricsServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>PrometheusServlet</servlet-name>
    <url-pattern>/metrics</url-pattern>
</servlet-mapping>

Step 3: Add an interceptor class

This will intercept all the requests coming to application and capture the metrics to be exposed to prometheus –

package com.myjavablog.config;

import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.Histogram;
import io.prometheus.client.Summary;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author anupb
 */

public class PrometheusMetricsInterceptor extends HandlerInterceptorAdapter {

    private static Logger logger = Logger.getLogger(PrometheusMetricsInterceptor.class);

    private static final Histogram requestLatency = Histogram.build()

            .name("service_requests_latency_seconds")

            .help("Request latency in seconds.")

            .labelNames("systemId", "appId", "type", "name", "method").register();


    private ThreadLocal<Histogram.Timer> timerThreadLocal;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        return super.preHandle(request, response, handler);

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        String name = this.getName(request, handler).toLowerCase();
        String method = request.getMethod().toUpperCase();

        timerThreadLocal = new ThreadLocal<>();
        timerThreadLocal.set(requestLatency.labels(name, method).startTimer());
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        super.afterCompletion(request, response, handler, ex);

        if (timerThreadLocal.get() != null) {
            timerThreadLocal.get().observeDuration();
        }
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        super.afterConcurrentHandlingStarted(request, response, handler);
    }

    private String getName(HttpServletRequest request, Object handler) {
        String name = "";

        try {
            if (handler != null && handler instanceof HandlerMethod) {

                HandlerMethod method = (HandlerMethod) handler;
                String className = ((HandlerMethod) handler).getBeanType().getName();
                name = className + "." + method.getMethod().getName();
            } else {
                name = request.getRequestURI();
            }

        } catch (Exception ex) {
            logger.error("getName", ex);
        } finally {
            return name;
        }
    }
}

Step 4: Add prometheus initialization configuration

This will expose the metrics to prometheus server –

package com.myjavablog.config;
 public class PrometheusConfig {

private static Logger logger = Logger.getLogger(PrometheusConfig.class);

 

@PostConstruct

public void initialize() {

logger.info("prometheus init...");

DefaultExports.initialize();

logger.info("prometheus has been initialized...");

}

}

Step 5: Add an interceptor to spring-mvc.xml

You need to first add the schema location as below –

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

Then you need to add below tag –

<mvc:interceptors>

<bean class="com.xx.config.PrometheusMetricsInterceptor"/>

</mvc:interceptors>

Step 6: Add configuration to applicationcontext.xml

<bean id="prometheusConfig" class="com.myjavablog.config.PrometheusConfig" init-method="initialize" />

Once all this configuration is done , you can add the application URL in prometheus.

These parameters are useful to monitor your spring MVC application.

Spring Bean Scopes

In this example , we will see bean scopes in spring container . In Spring 5 below scopes (websocket) have been  newly introduced –

SCOPE DESCRIPTION
singleton (default) Single bean object instance per spring IoC container
prototype Opposite to singleton, it produces a new instance each and every time a bean is requested.
request Return a single bean instance per HTTP request.Only valid in web-aware Spring ApplicationContext.
session Return a single bean instance per HTTP session.Only valid in web-aware Spring ApplicationContext.
application A single instance will be created and available during complete lifecycle of ServletContext.Only valid in web-aware Spring ApplicationContext.
websocket A single instance will be created and available during complete lifecycle of WebSocket.Only valid in web-aware Spring ApplicationContext.

Tools used to create below project – 

  1. Spring 5.0.7.RELEASE
  2. Maven 3.3
  3. Java 8
  4. Eclipse Neon.2

Github Link :   Download

Step 1: Create Simple Maven Project with Spring Configuration

Step 2: Configure maven dependencies

Below pom.xml file contains the dependencies required for spring project –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myjavablog</groupId>
<artifactId>SpringBeanScopesDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringBeanScopesDemo</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

</dependencies>
</project>

Below project structure will be created for you by Eclipse .

 

 

 

 

 

 

 

 

 

Step 3:  Create City.java under com.myjavablog.beans package –

City.java

package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class City {

String cityName;

public String getcityName() {
return cityName;
}

public void setcityName(String cityName) {
this.cityName = cityName;
}

}

These are bean files where we have only getters and setters defined.

Step 4: Create ApplicationContext.xml under /src/main/resources-

ApplicationContext.xml

<div id="crayon-5b537011533c5704156605-2" class="crayon-line crayon-striped-line">

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!-- Default Singleton scope bean -->
<bean id="CitySingletonBean" class="com.myjavablog.beans.City">
</bean>

<!-- Proptotype scope bean-->
<bean id="CityPrototypeBean" class="com.myjavablog.beans.City" scope="prototype">
</bean>

</beans>

</div>

Step 5: Create a BeanScopesMain.java under com.myjavablog package –

package com.myjavablog;

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

import com.myjavablog.beans.City;

public class BeanScopesMain {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext beanFactory = new ClassPathXmlApplicationContext("ApplicationContext.xml");

//Default Singleton scope bean
City singletonBeanInstance1 = (City) beanFactory.getBean("CitySingletonBean");
singletonBeanInstance1.setcityName("Pune");
System.out.println("Singleton Bean value: "+singletonBeanInstance1.getcityName()+"---------- Instance hashcode: "+singletonBeanInstance1.hashCode());

City singletonBeanInstance2 = (City) beanFactory.getBean("CitySingletonBean");
System.out.println("Singleton Bean value: "+singletonBeanInstance2.getcityName() +"---------- Instance hashcode: "+singletonBeanInstance2.hashCode());

//Proptotype scope bean
City prototypeBeanInstance1 = (City) beanFactory.getBean("CityPrototypeBean");
prototypeBeanInstance1.setcityName("Pune");

System.out.println("Prototype Bean value: "+prototypeBeanInstance1.getcityName()+"---------- Instance hashcode: "+prototypeBeanInstance1.hashCode());

City prototypeBeanInstance2 = (City) beanFactory.getBean("CityPrototypeBean");
prototypeBeanInstance2.setcityName("Pune");

System.out.println("Prototype Bean value: "+prototypeBeanInstance2.getcityName()+"---------- Instance hashcode: "+prototypeBeanInstance2.hashCode());

}
}

We have created ApplicationContext which actually loads bean definitions from XML configuration.

Output:

Singleton Bean value: Pune---------- Instance hashcode: 1509563803
Singleton Bean value: Pune---------- Instance hashcode: 1509563803
Prototype Bean value: Pune---------- Instance hashcode: 684874119
Prototype Bean value: null---------- Instance hashcode: 1157740463

In case of Singleton bean, When We firstly called getBean and retrieved city object and set cityName to “Pune” and when second time we called getBean method it did nothing but returned same object with cityName as “Pune”. Both the objects has same hashcodes as its same object.

In case of Prototype bean,When We firstly called getBean and retrieved city object and set cityName to “Pune”and when second time we called getBean method it returned new object with cityName as “null”. Both the objects has different hashcodes shows these are completely different and created freshly.

Step 6: Clean and install project

Now run the maven clean install phase as below –

Command:  mvn clean install

OR

Right click on project -> Debug As -> Maven build . Below popup will come up –


 

 

 

 

 

 

 

Step 7: Run the spring application as Java Application

 

 

 

 

 

 

 

 

Output:

Singleton Bean value: Pune---------- Instance hashcode: 1509563803
Singleton Bean value: Pune---------- Instance hashcode: 1509563803
Prototype Bean value: Pune---------- Instance hashcode: 684874119
Prototype Bean value: null---------- Instance hashcode: 1157740463

Spring Constructor Injection

In this example , we will see Second type of dependency injection in Spring i.e. Contructor Injection –

Tools used to create below project – 

  1. Spring 5.0.7.RELEASE
  2. Maven 3.3
  3. Java 8
  4. Eclipse Neon.2

Github Link :   Download

Step 1: Create Simple Maven Project with Spring Configuration

Step 2: Configure maven dependencies

Below pom.xml file contains the dependencies required for spring project –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myjavablog</groupId>
<artifactId>SpringConstructorInjection</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringConstructorInjection</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

</dependencies>
</project>

Below project structure will be created for you by Eclipse .


 

 

 

 

 

 

Step 3:  Create Employee.java and Address.java under com.myjavablog.beans package –

Employee.java

package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class Employee {

private String name;
private Address address;

public Employee(String name, Address address) {
super();
this.name = name;
this.address = address;
}

public String getName() {
return name;
}

public Address getAddress() {
return address;
}

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

}

Address.java

package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class Address {

private String city;
private String state;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

@Override
public String toString() {
return "Address [city=" + city + ", state=" + state + "]";
}

}

These are bean files where we have only getters and setters defined.

Step 4: Create ApplicationContext.xml under /src/main/resources-

ApplicationContext.xml

<div id="crayon-5b537011533c5704156605-2" class="crayon-line crayon-striped-line">

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<bean id="EmployeeBean" class="com.myjavablog.beans.Employee">
<constructor-arg index="0" type="java.lang.String" value="Anup" />
<constructor-arg index="1" ref="AddressBean" />
</bean>
<bean id="AddressBean" class="com.myjavablog.beans.Address">
<property name="city" value="Pune"></property>
<property name="state" value="Maharashtra"></property>
</bean>

</beans>

</div>

You must have noted here that, Employee class has dependency on Address class. So Address is injected into the Employee through Dependency Injection . And as we have initialized address object through constructor in Employee class this is called Constructor Dependency Injection. Here ref=”AddressBean” is a reference to AddressBean and its injected into Employee object through Employee Constructor.

Here We have declared two beans with corresponding ids.
1.Class Employee with id as “EmployeeBean”
2.Class Address with id as “AddressBean”
constructor-arg tag is used for providing argument to bean’ s

constructor.type is for declaring data types and index defines position in constructor’s argument.

In above xml,Two arguments are passed.
1. Anup as string
2. AddressBean‘s reference to Address Object

Step 5: Create a ConstructorMethodMain.java under com.myjavablog package –

package com.myjavablog;

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

import com.myjavablog.beans.Address;
import com.myjavablog.beans.Employee;

public class ConstructorMethodMain {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext beanFactory = new ClassPathXmlApplicationContext("ApplicationContext.xml");

Employee beanInstance = (Employee) beanFactory.getBean("EmployeeBean");

Address add = beanInstance.getAddress();
System.out.println("Employee Name:" + beanInstance.getName() +" City: "+ add.getCity() +" State: "+add.getState());
}
}

We have created ApplicationContext which actually loads bean definitions from XML configuration.

Step 6: Clean and install project

Now run the maven clean install phase as below –

Command:  mvn clean install

OR

Right click on project -> Debug As -> Maven build . Below popup will come up –


 

 

 

 

 

 

 

Step 7: Run the spring application as Java Application

 

 

 

 

 

 

 

 

Output:

Employee Name:Anup City: Pune State: Maharashtra

Spring Setter Injection

In this example , we will see first type of dependency injection in Spring i.e. Setter Injection –

Tools used to create below project – 

  1. Spring 5.0.7.RELEASE
  2. Maven 3.3
  3. Java 8
  4. Eclipse Neon.2

Github Link :   Download

Step 1: Create Simple Maven Project with Spring Configuration

Step 2: Configure maven dependencies

Below pom.xml file contains the dependencies required for spring project –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myjavablog</groupId>
<artifactId>SpringSetterInjection</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringSetterInjection</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

</dependencies>
</project>

Below project structure will be created for you by Eclipse .


 

 

 

 

 

 

Step 3:  Create Employee.java and Address.java under com.myjavablog.beans package –

Employee.java

/**
*
*/
package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class Employee {

private String name;
private Address address;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

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

}

Address.java

/**
*
*/
package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class Address {

private String city;
private String state;

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

@Override
public String toString() {
return "Address [city=" + city + ", state=" + state + "]";
}

}

These are bean files where we have getters and setters defined.

Step 4: Create ApplicationContext.xml under /src/main/resources-

ApplicationContext.xml

<div id="crayon-5b537011533c5704156605-2" class="crayon-line crayon-striped-line">

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<bean id="EmployeeBean" class="com.myjavablog.beans.Employee">
<property name="name" value="Anup" />
<property name="address" ref="AddressBean"></property>
</bean>

<bean id="AddressBean" class="com.myjavablog.beans.Address">
<property name="city" value="Pune" ></property>
<property name="state" value="Maharashtra"></property>
</bean>

</beans>

</div>

You must have noted here that, Employee class has dependency on Address class. So Address is injected into the Employee through Dependency Injection . And as we have initialized address object through setAddress() method in Employee class this is called Setter Dependency Injection. Here ref=”AddressBean” is a reference to AddressBean and its injected into Employee object.

Step 5: Create a SetterMethodMain.java under com.myjavablog package –

package com.myjavablog;

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

import com.myjavablog.beans.Address;
import com.myjavablog.beans.Employee;

public class SetterMethodMain {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext beanFactory = new ClassPathXmlApplicationContext("ApplicationContext.xml");

Employee beanInstance = (Employee) beanFactory.getBean("EmployeeBean");

Address add = beanInstance.getAddress();
System.out.println("Employee Name:" + beanInstance.getName() +" City: "+ add.getCity() +" State: "+add.getState());
}
}

We have created ApplicationContext which actually loads bean definitions from XML configuration.

Step 6: Clean and install project

Now run the maven clean install phase as below –

Command:  mvn clean install

OR

Right click on project -> Debug As -> Maven build . Below popup will come up –


 

 

 

 

 

 

 

Step 7: Run the spring application as Java Application

 

 

 

 

 

 

 

 

Output:

Employee Name:Anup City: Pune State: Maharashtra

Spring Inversion Of Control(IOC) vs Dependency Injection(DI)

Inversion Of Control (IOC)

This is common characteristic of frameworks, IOC manages java objects from instantiation to destruction through its BeanFactory.
Java components that are instantiated by the IoC container are called beans, and the IoC container manages a bean’s scope, lifecycle events, and any AOP features for which it has been configured and coded.

 

Dependency Injection(DI)

The basic concept of the dependency injection (also known as Inversion of Control pattern) is that you do not 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 components in a configuration file. An IOC container is then responsible for hooking it all up.

For example :

Suppose we have an object Employee and it has a dependency on object Address. So we define a bean corresponding to Employee where it will define its dependency on object Address. When Spring tries to create an Object Employee it sees that Employee has a dependency on object Address so first it will create the Address object (dependent object) and then inject this into the Employee Object.

Normal way (Without dependency Injection)

Here Employee class has dependency on address object. So we have instantiated address object in traditional way using new operator as below –

 

 

 

 

 

 

 

With Dependency Injection –

Here we have outsourced the object creation task to third party in our case it’s spring container. In spring these objects are called as beans. These beans can be configured using XML or Annotation based configuration as shown in earlier posts. Employee objects has a dependency on Address . So this dependency is injected by third party . This process is called  Dependency Injection (DI).

 

 

 

 

 

Benifits of Dependency Injection in Spring:

  • Ensures configuration and uses of services are separate.
  • Can switch implementations by just changing configuration.
  • Enhances Testability as mock dependencies can be injected.
  • Dependencies can be easily identified.

How to Implement Inversion of Control

In object-oriented programming, there are several basic techniques to implement inversion of control as below-

  1. Using a factory pattern
  2. Using a service locator pattern
  3. Using a dependency injection of any given below type:
    • a constructor injection
    • a setter injection
    • an interface injection

Constructor Injection

Constructor-based DI is realized by invoking a constructor with a number of arguments, each representing a collaborator. 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.

public class ConstructorDI {

DemoBean demoBean = null;

public TestSetterDI (DemoBean demoBean) {
this.demoBean = demoBean;
}
}

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.

public class SetterDI {

DemoBean demoBean = null;

public void setDemoBean(DemoBean demoBean) {
this.demoBean = demoBean;
}
}

Interface Injection

In this methodology we implement an interface from the IOC framework. IOC framework will use the interface method to inject the object in the main class. It is much more appropriate to use this approach when you need to have some logic that is not applicable to place in a property. Such as logging support.

public void SetLogger(ILogger logger)
{
_notificationService.SetLogger(logger);
_productService.SetLogger(logger);
}

Spring Annotation Based Configuration

In previous post we have seen how to configure spring using XML configuration. Now in this example , we will see spring configuration using annotations –

Tools used to create below project – 

  1. Spring 5.0.7.RELEASE
  2. Maven 3.3
  3. Java 8
  4. Eclipse Neon.2

Github Link :   Download

Step 1: Create Simple Maven Project with Spring Configuration

Step 2: Configure maven dependencies

Below pom.xml file contains the dependencies required for spring project –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myjavablog</groupId>
<artifactId>SpringAnnotationBasedConfiguration</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringAnnotationBasedConfiguration</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

</dependencies>
</project>

Below project structure will be created for you by Eclipse .


 

 

 

 

 

 

 

 

 

Step 3:  Create City.java under com.myjavablog.beans package –

package com.myjavablog.beans;

/**
* @author anupb
*
*/
public class City {

String cityName;

public City(String cityName) {
this.cityName = cityName;
}

public String getcityName() {
return cityName;
}

public void setcityName(String cityName) {
this.cityName = cityName;
}

}

This is the bean file where we have getters and setters defined.

Step 4: Create AnnotationConfig .java file under com.myjavablog.config package-

AnnotationConfig.java

/**
*
*/
package com.myjavablog.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.myjavablog.beans.City;

/**
* @author anupb
*
*/
@Configuration
public class AnnotationConfig {

@Bean(name="cityObj")
public City getCountry()
{
return new City("Pune");
}
}

This is Annotation based configuration to configure City bean. Its similar to XML based configuration which we did in previous post. The same Configuration can be done in XML as below –

<div id="crayon-5b537011533c5704156605-2" class="crayon-line crayon-striped-line"><?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<bean id="countryObj" class="org.arpit.java2blog.Country" >
<property name="countryName" value="India"/>
</bean>
</beans></div>

Step 5: Create a SpringJavaBasedConfigMain.java under com.myjavablog package –

package com.myjavablog;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.myjavablog.beans.City;
import com.myjavablog.config.AnnotationConfig;

/**
* Hello world!
*
*/
public class SpringJavaBasedConfigMain {
public static void main(String[] args) {

@SuppressWarnings("resource")
ApplicationContext appContext = new AnnotationConfigApplicationContext(AnnotationConfig.class);
City cityObj = (City) appContext.getBean("cityObj");
String cityName = cityObj.getcityName();

System.out.println("City name: " + cityName);
}
}

We have created ApplicationContext which actually loads bean definitions from annotation configuration i.e. AnnotationConfig.java

Step 6: Clean and install project

Now run the maven clean install phase as below –

Command:  mvn clean install

OR

Right click on project -> Debug As -> Maven build . Below popup will come up –


 

 

 

 

 

 

 

 

 

Step 7: Run the spring application as Java Application

 

 

 

 

 

 

 

 

Output:

City name: Pune

Spring Hello World

We will create a simple HelloWorld application using spring –

Tools used to create below project – 

  1. Spring 5.0.7.RELEASE
  2. Maven 3.3
  3. Java 8
  4. Eclipse Neon.2

Github Link :   Download

Step 1: Go to File -> New -> Project -> Maven Project . Select maven-archetype-quickstart and click Next.


 

 

 

 

 

 

 

 

Then you need to configure project name, group, artifact and package as shown below –


 

 

 

 

 

 

 

 

 

Step 2: Configure maven dependencies

Below pom.xml file contains the dependencies required for spring project –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myjavablog</groupId>
<artifactId>SpringHelloWorld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringHelloWorld</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Spring 5 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

</dependencies>
</project>

Below project structure will be created for you by Eclipse .


 

 

 

 

 

 

 

Step 3:  Create HelloWorldBean.java under com.myjavablog.beans package –

package com.myjavablog.beans;

/**
* Hello world!
*
*/
public class HelloWorldBean {
String name;

public void printHello() {
System.out.println("Hello World from " + name);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

This is the bean file where we have getters and setters defined.

Step 4: Create resources folder /src/main directory –

HelloWorld.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"
xmlns:context="http://www.springframework/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<bean id="HelloWorldBean" class="com.myjavablog.beans.HelloWorldBean">
<property name="name" value="Anup" />
</bean>

</beans>

This contains XML configuration for all the beans which we need to inject into our application.

Bean tag has attributes like –

id = Bean ID for unique identification

Class = Associate the bean class

property = To initialize various attributes of the bean

Step 5: Create a HelloWorldMain.java under com.myjavablog package –

package com.myjavablog;

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

import com.myjavablog.beans.HelloWorldBean;

/**
* @author anupb
*
*/
public class HelloWorldMain {

/**
* @param args
*/
public static void main(String[] args) {

ApplicationContext beanFactory = new ClassPathXmlApplicationContext("HelloWorld.xml");

HelloWorldBean beanInstance = (HelloWorldBean) beanFactory.getBean("HelloWorldBean");
beanInstance.printHello();
}

}

We have create ApplicationContext which actually loads XML bean definitions from class path resource i.e. HelloWorld.xml

Step 6: Clean and install project

Now run the maven clean install phase as below –

Command:  mvn clean install

OR

Right click on project -> Debug As -> Maven build . Below popup will come up –


 

 

 

 

 

 

 

Step 7: Run the spring application

 

 

 

 

 

 

 

 

Output:

Hello World from Anup

Spring IOC Container Types

Spring Container Types –

The Spring container is the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete life cycle from creation till destruction. The Spring container uses dependency injection (DI) to manage the components that make up an application.

Spring mainly provides following two types of containers – 

  1. BeanFactory container
  2. ApplicationContext container

1. BeanFactory container

A BeanFactory is essentially nothing more than the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. The BeanFactory enables you to read bean definitions and access them using the bean factory. When using just the  you would create one and read in some bean definitions in the XML format.

Below are the ways to create BeanFactory –

InputStream is = new FileInputStream("beans.xml");
BeanFactory factory = new XmlBeanFactory(is);
//Get bean
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");

Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
//Get bean
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");

ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
//Get bean
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");

2. ApplicationContext container

This container adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContext interface.

The ApplicationContext container includes all functionality of the BeanFactory container, so it is generally recommended over the BeanFactoryBeanFactory can still be used for lightweight applications like mobile devices or applet based applications where data volume and speed is significant.

The most commonly used ApplicationContext implementations are:

  1. FileSystemXmlApplicationContext: This container loads the definitions of the beans from an XML file. You need to provide the full path of the XML bean configuration file to the constructor.
  2. ClassPathXmlApplicationContext This container loads the definitions of the beans from an XML file. You do not need to provide the full path of the XML file but you need to set CLASSPATH properly because this container will look bean configuration XML file in CLASSPATH.
  3. WebXmlApplicationContext: This container loads the XML file with definitions of all beans from within a web application.

A sample code for application context instantiation is as below.

ApplicationContext context = new FileSystemXmlApplicationContext("beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

 

Cheers!!!!!!

Spring Introduction

Introduction – 

Spring is an open source framework created to address the complexity of enterprise application development.Spring is one of the most popular frameworks for Java enterprise edition.Spring framework was designed by Rod Johnson. Since then Spring has became alternative technology in java world for EJB model. One of the chief advantages of the Spring framework is its layered architecture, which allows you to be selective about which of its components you use while also providing a cohesive framework for J2EE application development .

Below Spring frameworks has been released till date –

  • On Jun 2003– Took license from Apache and First released as a Framework.
  • Jan 2006- Won the two awards Jolt productivity award and JAX Innovation Award.
  • On Oct 2006– Spring 2.0 released.
  • On Nov 2007– Spring 2.5 released.
  • On Dec 2009 – Spring 3.0 released.
  • On Dec 2011– Spring 3.1 released.
  • On Jun 2012– Spring 3.2 released.
  • On December 2013– Spring 4.0 released.
  • On 31 July 2015– Spring 4.2 released.
  • On 10 June 2016– Spring 4.3 released.
  • On July 28, 2016 Spring 5   released . New features introduced in Spring 5 are –
    • JDK baseline update – JDK 1.8 or above
    • Core framework revision.
    • Core container updates.
    • Functional programming with Kotlin.
    • Reactive Programming Model.
    • Testing improvements.
    • Library support.
    • Discontinued support.

Features – 

Inversion Of Control (IOC)

Basic concept of the Dependency Injection or Inversion of Control is that, we do not need to create the objects, instead just describe how it should be created. No need to directly connect your components and services together in program, instead just describe which services are needed by which components in a configuration file/xml file. The Spring IOC container is then responsible for binding it all up.

Dependency Injection

It is a composition of structural design patterns, in which for each function of the application there is one, a conditionally independent object (service) that can have the need to use other objects (dependencies) known to it by interfaces. Dependencies are transferred (implemented) to the service at the time of its creation. This is a situation where we introduce an element of one class into another. In practice, DI is implemented by passing parameters to the constructor or using setters. Libraries that implement this approach are also called IoC containers.

Lightweight

Spring is lightweight when it comes to size and transparency. The basic version of spring framework is around 1MB. And the processing overhead is also very negligible.

Container

Spring container manages the life cycle and configuration of application objects.

MVC Framework

Spring comes with MVC web application framework, built on core Spring functionality. This framework is highly configurable via strategy interfaces, and accommodates multiple view technologies like JSP, Velocity, Tiles and POI. But other frameworks can be easily used instead of Spring MVC Framework.

Architecture – 

  • Spring Core

    The Core package is the most import component of the Spring Framework.
    This component provides the Dependency Injection features. The BeanFactory  provides a factory pattern which separates the dependencies like initialization, creation and access of the objects from your actual program logic.

  • Spring Context

    This package builds on the beans package to add support for message sources and for the Observer design pattern, and the ability for application objects to obtain resources using a consistent API.

  • Spring AOP

    One of the key components of Spring is the AOP framework. AOP is used in Spring:

    • To provide declarative enterprise services, especially as a replacement for EJB declarative services. The most important such service is declarative transaction management, which builds on Spring’s transaction abstraction.
    • To allow users to implement custom aspects, complementing their use of OOP with AOP
  • Spring ORM

    The ORM package is related to the database access. It provides integration layers for popular object-relational mapping APIs, including JDO, Hibernate and iBatis.

  • Spring Web

    The Spring Web module is part of Spring?s web application development stack, which includes Spring MVC.

  • Spring DAO

    The DAO (Data Access Object) support in Spring is primarily for standardizing the data access work using the technologies like JDBC, Hibernate or JDO.

  • Spring Web MVC

    This is the Module which provides the MVC implementations for the web applications.

  • Spring Test

    This module covers the testing of Spring components with TestNG or JUnit. It balances the consistency of loading in ApplicationContexts and caching of them in Spring. Mock objects are created to test the code in isolation.

 

Bitnami