“First do it, then do it right, then do it better.“ (Addy Osmani)
Spring Boot 2.2 has recently been released and comes out with a range of new features. Among the dependency upgrades for quite a large number of Spring projects, some more changes in Spring Boot 2.2 are as follows:
- Support for Java 13
- JUnit 5
- Jakarta EE dependencies
- Lazy initialization
- RSocket support
- Hibernate dialect
- Kubernetes detection
- And others like: Health indicator groups, AssertJ 3.12, Spring HATEOAS 1.0, DataSize migration, Elasticsearch, Actuator HTTP Trace and Auditing, Gradle requirements, Jetty logging configuration, Hamcrest 2.1, Freemarker templates configuration, HttpHiddenMethodFilter disabled by default, Health Indicator, Test Application Arguments, Banners …
I decided not to describe every feature in detail but to focus on the changes I found to be the most interesting.
Deprecations
To begin with, I’d like to draw your attention to the deprecations introduced in Spring Boot 2.1 that have been completely removed in the new version (2.2). Therefore, if you want to migrate from older versions you have to get rid of all the deprecated methods used in your project.
You can find more information by searching the list of classes, methods, interfaces and other deprecated contents by accessing the Spring docs web page. (for example: https://docs.spring.io/spring-boot/docs/current/api/deprecated-list.html)
Java 13 support
An interesting part of Spring Boot is the fact that it not only supports Java 8 and 11 but it is also compatible with the new Java 13 version that has been released very recently (as of September, 17th 2019).
JUnit Jupiter (JUnit 5)
The feature-rich unit testing library JUnit 5 has been added as default support to the Spring Boot 2.2 Starter Application. This means that JUnit 5 is the default test library dependency.
The following Wrappers should be used in order to run the test:
- Maven Wrapper:
./mvnw clean test
- Gradle Wrapper:
./gradlew clean test
If you access the Spring Boot starter page http://start.spring.io and generate a project, you will find out that the created project contains all the required dependencies for JUnit 5.

(https://start.spring.io
The generated demo test class is shown below:
package com.helloworld.example; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class HelloWorldApplicationTests @Test void contextLoads() { } }
Furthermore, if you are still using JUnit 4 and want to migrate to the new Spring Boot version you don’t have to worry or migrate everything to JUnit 5 because JUnit 5’s engine supports existing JUnit 4 test classes.
Supposing that you use Maven with the Maven Surefire plugin for JUnit 4, there are some things such as the listener property you have take into consideration. For an example of this, you can refer to the release notes for Spring Boot 2.2.
Another key point to take into consideration is the creation of Spring Boot tests. First of all, you can create a Spring Boot test utilizing a web server that runs on a random port (@LocalServerPort)
or using a web server running on a random port with a mocked dependency (@MockBean
). Secondly, you can create a Spring Boot test with a mocked layer using the following annotation: @AutoConfigureMockMvc.
Other test dependency upgrades for Spring Boot 2.2 are AssertJ 3.13.2, Hamcrest 2.1, and Mockito 3.1.0.
Jakarta EE dependencies
If you haven’t heard of Jakarta EE that’s not a worry. Jakarta EE is the specification for Java Enterprise Edition going forward. Jakarta EE is Java’s key for the focus on cloud computing. If you are interested in this subject you can read the articles from the https://www.eclipse.org newsletter.
Getting back to our topic, in Spring Boot 2.2 some of the dependencies have been moved from Java EE to Jakarta EE dependencies:
javax
group ID ->jakarta
group ID
Notice that you now should move to the Jakarta EE API dependencies because the Java EE API dependencies will ultimately be eliminated.
Lazy Initialization
A new property has been introduced in Spring Boot 2.2 in order to enable the lazy initialization. This is also possible in older versions but the process to have the lazy initialization enabled is quite difficult because you need to write a BeanFactoryPostProcessor
. In Spring Boot 2.2 you can enable it by setting the spring.main.lazy-initialization
to true.
Its advantages are the reduced start-up times because fewer classes are loaded and fewer beans are created during the application startup.
If you wonder why I didn’t mention Spring Boot’s DevTools, here is the answer: Spring Boot already contains DevTools that helps increase your productivity. Instead of restarting the JVM and application every time a new change was made, DevTools uses hot restart in the same JVM instance. Even if the original time is reduced by 80% after the restart, when using spring.main.lazy-initialization
it decreases even more, by 64% directly in the IDE.
But why is it not enabled by default?
This can produce problems that should have been pointed out at start-up because there are classes that won’t load anymore or beans that are not created until they are necessary. The produced errors should include:
- NoClassDefFoundError
- OutOfMemoryError
- Failures due to misconfiguration
In order to enable the lazy initialization, you must add the following line to the configuration file:
spring.main.lazy-initialization=true
This applies to all beans.
If you need this configuration for all beans except one (or more) you can use: @Lazy(false)
. Moreover, if you need one specific bean to be configured with lazy initialization, the @Lazy
annotation should be used.
The @Lazy
annotation is applied as follows. If a class is annotated with @Lazy
, it means that all the methods annotated with @Bean
will be lazy. For instance, in the example below only the address will be loaded lazily.
@Lazy @Configuration public class HelloWorld { @Bean public Address getAddress() { return new Address(); } public Name getName() { return new Name(); } public Company getCompany() { return new Company(); } }
If @Lazy
is removed from the class and is added to a @Bean
declaration, it means that the lazy loading only affects that specific bean.
@Configuration public class HelloWorld { @Bean @Lazy(true) public Address getAddress() { return new Address(); } public Name getName() { return new Name(); } }
Kubernetes detection
Kubernetes is an Open Source container management tool by Google.
Notable is the fact that by using @ConditionalOnCloudPlatform
on a class you can check if the application is running on Kubernetes.
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) public class DemoApplication { //… }
Other new features and performance improvements include the fact that configuration properties now support constructor-based binding, the ability to group health indicators and an extensive self-configuration of Spring Boot’s RSocket implementation. RSocket is an application protocol that provides Reactive Streams semantics. spring-boot-starter-rsocket
is now part of Spring Boot starter.
All things considered, I think you should definitely try out Spring Boot 2.2 in order to code more comfortably.

