Book Image

Hands-On High Performance with Spring 5

By : Chintan Mehta, Subhash Shah, Pritesh Shah, Prashant Goswami, Dinesh Radadiya
Book Image

Hands-On High Performance with Spring 5

By: Chintan Mehta, Subhash Shah, Pritesh Shah, Prashant Goswami, Dinesh Radadiya

Overview of this book

While writing an application, performance is paramount. Performance tuning for real-world applications often involves activities geared toward detecting bottlenecks. The recent release of Spring 5.0 brings major advancements in the rich API provided by the Spring framework, which means developers need to master its tools and techniques to achieve high performance applications. Hands-On High Performance with Spring 5 begins with the Spring framework's core features, exploring the integration of different Spring projects. It proceeds to evaluate various Spring specifications to identify those adversely affecting performance. You will learn about bean wiring configurations, aspect-oriented programming, database interaction, and Hibernate to focus on the metrics that help identify performance bottlenecks. You will also look at application monitoring, performance optimization, JVM internals, and garbage collection optimization. Lastly, the book will show you how to leverage the microservice architecture to build a high performance and resilient application. By the end of the book, you will have gained an insight into various techniques and solutions to build and troubleshoot high performance Spring-based applications.
Table of Contents (14 chapters)

Spring's IoC container

Spring's IoC container is built as the core module of the Spring architecture. IoC is also known as DI. It is a design pattern which eliminates the dependency of the code to provide ease in managing and testing the application. In DI, the objects themselves characterize their dependencies with the other objects they work, just through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is created or returned from a factory method.

The container is then responsible to inject those dependencies when it creates the bean. This process is basically the inverse (so it is known as IoC) of the bean itself controlling the instantiation or location of its dependencies, by using the direct construction of classes, or a mechanism.

There are two main base packages of the Spring Framework's IoC container: org.springframework.beans, and org.springframework.context. The BeanFactory interface provides some of the advanced-level configuration mechanisms to manage any type of object. ApplicationContext includes all the functionalities of BeanFactory, and acts as a subinterface of it. In fact, ApplicationContext is also recommended over BeanFactory, and provides more supporting infrastructure that enables: easier integration with Spring's AOP features and transaction; message resource handling in terms of internationalization and event publication; and application layer-specific contexts such as WebApplicationContext for use in web applications.

The interface org.springframework.context.ApplicationContext is represented as the Spring IoC container, and it is in complete control of a bean's life cycle and responsible for instantiating, configuring, and assembling the beans.

The container gets all the instructions to instantiate, configure, and assemble, by scanning bean configuration metadata. The configuration metadata can be represented using the following methods:

  • XML-based configuration
  • Annotation-based configuration
  • Java-based configuration

We will learn these methods in more detail in Chapter 2, Spring Best Practices and Bean Wiring Configurations.

The following diagram represents a simple representation of the Spring Container process towards creating a fully configured application:

The Spring IoC container

The following example shows the basic structure of XML-based configuration metadata:

<?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">

<!-- All the bean configuration goes here -->
<bean id="..." class="...">

</bean>

<!-- more bean definitions go here -->

</beans>

The id attribute is a string that you use to identify the individual bean definition. The class attribute defines the type of bean, and uses the fully qualified class name. The value of the id attribute refers to collaborating objects.

What are Spring beans?

You can consider a Spring bean as a simple Java object, instantiated, configured, and managed by a Spring IoC container. It is called a bean instead of an object or component because it is a replacement for complex and heavy enterprise JavaBeans with respect to the origin of the framework. We will learn more about Spring bean instantiation methods in Chapter 2, Spring Best Practices and Bean Wiring Configurations.

Instantiating a Spring container

For creating bean instances, we first need to instantiate a Spring IoC container by reading the configuration metadata. After initialization of an IoC container, we can get the bean instances using the bean name or ID.

Spring provides two types of IoC container implementations:

  • BeanFactory
  • ApplicationContext

BeanFactory

The BeanFactory container acts as the simplest container providing basic support for DI, and it is defined by the org.springframework.beans.factory.BeanFactory interface. BeanFactory is responsible to source, configure, and assemble the dependencies between objects. BeanFactory mainly acts as an object pool, where object creation and destruction is managed through configuration. The most popular and useful implementation of BeanFactory is the org.springframework.context.support.ClassPathXmlApplicationContext. The ClassPathXmlApplicationContext uses XML configuration metadata to create a fully configured application.

The following sample defines a simple HelloWorld application using ClassPathXmlApplicationContext. The content of Beans.xml looks as follows:

<?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="bankAccount"
class="com.packt.springhighperformance.ch1.bankingapp.BankAccount">
<property name="accountType" value="Savings Bank Account" />
</bean>
</beans>

The preceding XML code represents the content of bean XML configuration. It has a single bean configured, which has a single property with the name message. It has a default value set for the property.

Now, the following Java class represents bean configured in the preceding XML.

Let's have a look at HelloWorld.java:

package com.packt.springhighperformance.ch1.bankingapp;

public class BankAccount {
private String accountType;

public void setAccountType(String accountType) {
this.accountType = accountType;
}

public String getAccountType() {
return this.accountType;
}
}

At the end, we need to use ClassPathXmlApplicationContext to create the HelloWorld bean and invoke a method in the created Spring bean.

Main.java looks as follows:

package com.packt.springhighperformance.ch1.bankingapp;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.
support.ClassPathXmlApplicationContext;

public class Main {

private static final Logger LOGGER = Logger.getLogger(Main.class);

@SuppressWarnings("resource")
public static void main(String[] args) {
BeanFactory beanFactory = new
ClassPathXmlApplicationContext("Beans.xml");
BankAccount obj = (BankAccount) beanFactory.getBean("bankAccount");
LOGGER.info(obj.getAccountType());
}
}

ApplicationContext

The ApplicationContext container provides support to access application components using BeanFactory methods. This includes all functionality of BeanFactory. In addition, ApplicationContext can also perform more enterprise functionalities, like transaction, AOP, resolving text messages from properties files, and pushing application events to interested listeners. It also has the ability to publish events to the registered listeners.

The mostly-used implementations of ApplicationContext are FileSystemXmlApplicationContext, ClassPathXmlApplicationContext, and AnnotationConfigApplicationContext.

Spring also provides us with a web-aware implementation of the ApplicationContext interface, as shown:

  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext

We can use either one of these implementations to load beans into a BeanFactory; it depends upon our application configuration file locations. For example, if we want to load our configuration file Beans.xml from the filesystem in a specific location, we can use a FileSystemXmlApplicationContext class that looks for the configuration file Beans.xml in a specific location within the filesystem:

ApplicationContext context = new
FileSystemXmlApplicationContext("E:/Spring/Beans.xml");

If we want to load our configuration file Beans.xml from the classpath of our application, we can use ClassPathXmlApplicationContext class provided by Spring. This class looks for the configuration file Beans.xml anywhere in the classpath, including JAR files:

ApplicationContext context = new
ClassPathXmlApplicationContext("Beans.xml");

If you are using a Java configuration instead of an XML configuration, you can use AnnotationConfigApplicationContext:

ApplicationContext context = new
AnnotationConfigApplicationContext(AppConfig.class);

After loading the configuration files and getting an ApplicationContext, we can fetch beans from the Spring container by calling the getBean() method of the ApplicationContext:

BankAccountService bankAccountService =
context.getBean(BankAccountService.class);

In the following section, we will learn about the Spring bean life cycle, and how a Spring container reacts to the Spring bean to create and manage it.

Spring bean life cycle

The factory method design pattern is used by the Spring ApplicationContext to create Spring beans in the container in the correct order, as per the given configuration. So, the Spring container is responsible for managing the life cycle of the bean, from creation to destruction. In a normal Java application, a new keyword of Java is used to instantiate the bean, and it's ready to use. Once the bean is no longer in use, it's eligible for garbage collection. But in a Spring container, the life cycle of the bean is more elaborate.

The following diagram illustrates the life cycle of a typical Spring bean:

Spring bean life cycle

In the next section, we will see the new features of the Spring Framework 5.0.