mutlugazete.com

Revolutionizing Application Launch: Multithreaded Bean Initialization in Spring 6.2

Written on

Chapter 1: Introduction to Spring 6.2

Spring 6.2.0 has introduced an exciting feature known as Parallel Bean Initialization, designed to dramatically improve the startup speed of applications. This advancement allows multiple Beans to be initialized at the same time during the startup phase, significantly cutting down on the overall launch time. Through well-structured concurrency control, Spring effectively manages Bean dependencies while maximizing parallel execution. This means even intricate Bean dependency structures can be handled efficiently, mitigating initialization conflicts or errors. Experience the future of rapid application launches with Spring 6.2!

Section 1.1: Understanding the Feature

Historically, Spring applications would initialize Beans in a predetermined order, which limited the potential for parallel processing and consequently slowed down the startup time. With the advent of Spring 6.2.0, the framework facilitates simultaneous Bean initialization, leading to a notable reduction in startup duration.

The implementation relies on a meticulously crafted concurrency control system that maintains the necessary dependencies among Beans while promoting parallelism. Thus, even with complex interdependencies, the Spring framework can adeptly manage the initialization process, preventing conflicts or issues.

Section 1.2: Practical Implementation

Before utilizing this feature, ensure that your project is configured to use Spring Framework 6.2 in your pom.xml file. This is crucial to avoid issues with missing dependencies. To set this up, specify the Spring-bom version number ahead of your dependencies as follows:

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-framework-bom</artifactId>

<version>6.2.0-M1</version>

<type>pom</type>

<scope>import</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-dependencies</artifactId>

<version>${spring.boot.version}</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

Subsection 1.2.1: Setting Up the Environment

Here’s how to define two services that simulate time-consuming tasks:

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j

public class CommonService {

public CommonService() {

try {

TimeUnit.SECONDS.sleep(3);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

log.info("CommonService initialized ...");

}

}

@Slf4j

public class OrderService {

public OrderService() {

try {

TimeUnit.SECONDS.sleep(3);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

log.info("OrderService initialized ...");

}

}

Both constructors simulate lengthy operations. Next, configure the application context:

@Configuration

public class AppConfig {

@Bean

public OrderService orderService() {

return new OrderService();

}

@Bean

public CommonService commonService() {

return new CommonService();

}

}

Section 1.3: Traditional vs. Concurrent Bean Initialization

To compare traditional Bean initialization, use the following code:

@SpringBootApplication

@Slf4j

public class SpringTestApp {

public static void main(String[] args) {

StopWatch stopWatch = new StopWatch();

stopWatch.start("Spring Startup");

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

stopWatch.stop();

log.info(stopWatch.prettyPrint());

context.close();

}

}

Output:

09:58:17.286 [main] INFO com.example.springtest.service.OrderService -- OrderService initialized ...

09:58:20.306 [main] INFO com.example.springtest.service.CommonService -- CommonService initialized ...

09:58:20.368 [main] INFO com.example.springtest.SpringTestApp -- Stopwatch '': 6.925379375 seconds

This indicates a total startup time of 6.9 seconds.

Now, let's implement concurrent Bean initialization with modifications in the @Bean definitions:

@Configuration

public class AppConfig {

@Bean(bootstrap = Bean.Bootstrap.BACKGROUND)

public OrderService orderService() {

return new OrderService();

}

@Bean(bootstrap = Bean.Bootstrap.BACKGROUND)

public CommonService commonService() {

return new CommonService();

}

@Bean

public Executor bootstrapExecutor() {

ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();

taskExecutor.setCorePoolSize(5);

taskExecutor.setMaxPoolSize(5);

taskExecutor.initialize();

return taskExecutor;

}

}

This configuration enables background multithreaded loading of Beans. Without setting the executor, the application will revert to main thread execution, negating the benefits of this enhancement.

Output:

10:36:57.803 [bootstrapExecutor-2] INFO com.example.springtest.service.CommonService -- CommonService initialized ...

10:36:57.803 [bootstrapExecutor-1] INFO com.example.springtest.service.OrderService -- OrderService initialized ...

10:36:57.982 [main] INFO com.example.springtest.SpringTestApp -- Stopwatch '': 3.784657208 seconds

This shows a total startup time of just 3.7 seconds, effectively doubling the speed of initialization thanks to the use of asynchronous threads.

Chapter 2: Understanding the Implementation Principles

The Spring container's startup process and the new refresh method are crucial to grasping this feature.

public abstract class AbstractApplicationContext {

public void refresh() {

finishBeanFactoryInitialization(beanFactory);

}

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

if (beanFactory.containsBean(BOOTSTRAP_EXECUTOR_BEAN_NAME) &&

beanFactory.isTypeMatch(BOOTSTRAP_EXECUTOR_BEAN_NAME, Executor.class)) {

beanFactory.setBootstrapExecutor(

beanFactory.getBean(BOOTSTRAP_EXECUTOR_BEAN_NAME, Executor.class)

);

}

beanFactory.preInstantiateSingletons();

}

}

In conclusion, the introduction of multithreaded Bean instantiation in Spring 6.2 significantly accelerates application startup. With its official release, many developers are expected to adopt this impressive feature.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Embracing Imperfections: A Path to Authentic Productivity

Discover how to overcome perfectionism to boost your productivity and embrace your journey of growth.

# Insights Gained from Observing American Greed's Lessons

Discover valuable life lessons from the series American Greed that can improve your financial literacy and personal integrity.

Optimizing Option Trading with Python: A Technical Overview

Explore how to utilize Python for stock selection in options trading through technical indicators.