This chapter will introduce the reader to Spring Boot and explain how it stands out from other competing frameworks. It will begin by explaining how to get started developing applications using Spring Boot. Also, it will explain about Spring Boot 1.x and the improvements introduced in Spring Boot 2.0. Furthermore, it will walk through the most noticeable features and/or improvements of Spring Boot 2.0. Continuing on, it will explain progress with Spring Boot 2.0 and supply tips on migration from the older versions to Spring Boot 2.0.
This chapter covers the following topics:
- Understanding Spring Boot
- Generating Spring Boot Projects
- Getting started with Spring Boot
- Changes since Spring Boot 1.x
- The next milestone
- Migration
Technical requirements for this chapter are as follows:Â
- To install Java Development Kit (JDK) 8, it can be downloaded from its official page at http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- To install Maven 3, download it from its official page at https://maven.apache.org/download.cgi
- To install IntelliJ IDEA, download it from its official page at https://www.jetbrains.com/idea/download/
- To install Spring Tool Suite(STS), download it from its official page at https://spring.io/tools
In this book, we will be using http://start.spring.io, which is a convenient tool for generating Spring Projects with the required dependencies to get started. This tool supports multiple Spring Boot versions, programming languages (Java
, Groovy
, Kotlin
), project types (Maven
, Gradle
), and dependencies. Learning to use this tool will help readers to get started quickly with Spring Projects. The following is a screenshot of the tool to help us get familiarized with it:

This tool allows the selection of a Project type (Maven Project
, Gradle Project
), programming language (Java
, Groovy
, Kotlin
), Spring Boot version (2.0.*
, 1.5.*
), project artifact group, artifact name, and project dependencies. After selecting the correct options, click on Generate Project
will download a ZIP file of the project.
The ZIP file needs to be extracted first before being used. The extracted ZIP file will have the following structure:
<Project Name>/ âââ src/ âââ pom.xml âââ mvnw âââ mvnw.bat
To open the generated project with IntelliJ, we perform the following steps:
- Open IntelliJ IDE.
- Select
File
|Open
from the menu bar as shown in the following screenshot:

- Navigate to the location where the extracted project is and click on
OK
after selecting the project, shown as follows:

- The IDE will show the opened project.
To open the generated project the Spring Tool Suite, we perform the following steps:
- Open STS.
- Select
File
|Open Projects from File Sys
tem...
from the menu bar, as shown in the following screenshot:

- From the dialog box that launched, click on theÂ
Directory...
button:

- Navigate to the extracted project location and Click on
OK
after selecting the project:

- Finally, click on
Finish
on the import projects dialog box. - The IDE will show the opened project.
The source code for this chapter can be found at https://github.com/PacktPublishing/Spring-Boot-2.0-Projects-Fundamentals-of-Spring-Boot-2.0, in the Chapter01
directory.
This section will enable readers to get started with Spring Boot by explaining its features in detail. Furthermore, it will help you get started with Spring Boot application development by explaining the bare-bones of a Spring Boot application. Furthermore, it will explain the Spring Framework ecosystem and how it can be used in the Spring Boot application to harness the power of time-tested, industry-standard databases, messaging systems, and so on.
Spring Boot is an application development framework for the Java virtual machine (JVM) that enables users to write stand-alone, production-grade, flexible, and extensible Spring-based applications with minimum code and configurations. This follows the Rapid application development (RAD) paradigm where the focus is on writing business logic that matters. With the introduction of cloud-based hosting services and microservice architectures, Spring Boot has been further elevated into a must-know technology platform. The following are some of its features:
- Standalone: A Spring Boot application is self-contained and easily deployable. It can start with its own embedded Tomcat, Jetty, Undertow web container, or as a console application from a just standard file such as Java Archive (JAR) or Web Archive (WAR). An example of this would be an application that has
spring-boot-starter-web
as a dependency, which when run will by default inside an embedded Tomcat web container. - Production-grade: A Spring Boot application enables most of the features required for production, such as monitoring, connection pools, externalized configurations, and so on, out of the box, and ships with industry-standard, time-tested, and proven third-party applications such as Tomcat.Â
- Flexible: A Spring Boot application will have most of its settings auto-configured with default settings based on the dependencies available in the classpath of the application. But the auto-configuration will step back whenever a custom configuration is made. An example for this would be when a Spring Boot application finds a MySQL JDBC driver in the classpath; it auto-configures DataSource, which connects to the host localhost and portÂ
3306
, as those will be the settings for a MySQL Server with a default installation. - Extensible: A Spring Boot application will have most core functionalities implemented out of the box, but also has a lot of Service Provider Interfaces (SPI), which are used by third-party developers to implement or modify functionality. An example of this would be when a requirement arises for a custom endpoint in Spring Boot Actuator; extending and overriding theÂ
AbstractEndpoint.invoke
 method in a Spring Bean will expose it as a new endpoint under Spring Boot Actuator.Â
Spring Boot does not do any code generation and does not require any XML files to be configured in order to run. Spring Boot is ideal for on-premise and cloud-based deployments with a quick boot-up time and a good memory footprint. The uniqueness of Spring Boot comes from its ecosystem of Spring modules, which covers security, data persistence, batch processing, and so on and from the highly active, competent community of developers who keep on improving the Spring Boot Framework.
The anatomy of a Spring Boot application will be that it will be inheriting from a spring-boot-starter-parent
project that will in return have all the common dependencies available for a Spring Boot application. Apart from this, there will be one or more spring-boot-starter
POMÂ such as spring-boot-starter-web
, spring-boot-starter-jpa
, and so on. The following example excerpt from pom.xml
shows the basic dependencies of a Spring Boot application:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> ... </dependencies>
The minimum bootstrapping point of a Spring Boot application will be a class with a main
method that will be annotated with a @SpringBootApplication
annotation along with the main
method body, which calls the SpringApplication.run
 static method, for which a configuration class (a class with @Configuration
annotationâthe @SpringBootApplication
annotation transitively has one) needs to be passed, along with a String array of arguments. The following code shows the minimum bootstrapping point of a Spring Boot application:
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringBootIntroApplication { public static void main(String[] args) { SpringApplication.run(SpringBootIntroApplication.class, args); } @Bean public ApplicationRunner applicationRunner() { return args -> { System.out.println("Hello, World!"); }; } }
By running the preceding class, a Spring Boot application can be provisioned and executed. There are several ways to run a Spring Boot application; some of them are mentioned here:
- Running the Spring Boot application
main
class using an IDE. - Building a JAR or WAR file using the following Maven command and then running:
$ mvn clean install $ java -jar target/<package-name>.[jar|war]
$ mvn clean spring-boot:run
The @SpringBootApplication
 annotation comprises of @EnableAutoConfiguration
 and @ComponentScan
annotations that do the heavy lifting of auto-configuring the Spring Boot application with the default settings and scanning the packages for any Spring-specific components such as services, components, repositories, and so on.
What made the Spring Boot application development framework stand out from other competing alternatives is the fact that it has a lot of supporting frameworks for easing development, with starter dependencies that cover industry-standard, enterprise-grade methodologies and tools such as Web MVC, JPA, MongoDB, Elasticsearch, Redis, and many more.
This makes Spring Boot a unique solution for day-to-day programming needs. By including a starter dependency, a Spring Boot application will have all the necessary dependencies and auto-configurations included in the application without any developer intervention.Â
This makes the life of a developer easy and enables us to focus on the business logic of the application instead of configurations and dependency management. At the time of writing, there are more than thirty of these starters available to be used in a Spring Boot application. The complete list can be found at https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters.
Spring Boot is a powerful framework as it has a very gradual learning curve and is built on the basis of the ability to write applications that just run with minimal effort. Having said that, Spring Boot should not be mistaken for a silver-bullet solution for all problems. In the areas of memory utilization, optimization, latency reduction, and many more, work may be needed, so developer commitment and effort are still required. But all in all, Spring Boot can be considered as a very good solution as it enables users to develop a minimum viable product (MVP) that is production-ready within maybe a couple of days or hours.
The last released version of Spring Boot 1.x was 1.5.10.RELEASE, after which Spring Boot 2.0 was released in early 2018. As Spring Boot 2.0 is a major release it has JVM level, platform level, application programming interface (API) level, and dependencies level changes, which must be taken into account when developing applications with Spring Boot 2.0.
The major changes from Spring Boot 1.x to Spring Boot 2.0 are listed as follows:
- Java 8 is the baseline and Java 9 is supported: This means the minimum JVM version on which a Spring Boot 2.0 application can be run is now Java 8 because the framework is modified to use many features introduced in Java 8. Furthermore, Spring Boot 2.0 is fully supported to run on Java 9, which means all the dependency JARs shipped will have module descriptors to support the Java 9 module system.
- Third-party libraries upgraded: Spring Boot 2.0 requires Spring Framework 5.0 along with Tomcat 8.5, Flyway 5, Hibernate 5.2, and Thymeleaf 3.
- Reactive Spring supported: Supports the development of functional, non-blocking, and asynchronous applications out of the box. Reactive Spring will be explained and used extensively in upcoming chapters.
- Micrometer Framework introduced for metrics: Uses Micrometer instead of its own API for metrics. A micrometer is a third-party framework that allows dimensional metrics.
- Spring Boot Actuator changed: Spring Boot Actuator endpoints are now placed inside the context path
/actuator
 instead of being mapped directly toroot
, to avoid path collisions. Additionally, a new set of endpoint annotations have been introduced to write custom endpoints for Spring Boot Actuator. - Configuration property binding: Improved relaxed binding of properties, property origins, converter support, and a new Binder API.
- Kotlin language supported: Supports Kotlin, a new concise and interoperable programming language introduced by IDEA. Kotlin will be explained in detail in Chapter 04, Introduction to Kotlin.
- HikariCP shipped out of the box instead of Tomcat Connection Pool: HikariCP is the most efficient, high-performing database connection pool available for the JVM and it is shipped by default with Spring Boot 2.0.
- A new way to dynamically register Spring Bean with
ApplicationContextInitializer
:Â Adds to previous methods of registering a Spring Bean by providing the means to define it in an XML file, annotateÂ@Bean
on a method that returns an object, annotate withÂ@Component
,@Service
,@Repository
annotations, and so on. Spring Framework 5 has introducedÂApplicationContextInitializer
, which can do dynamic registering. - HTTP/2 supports out of the box: HTTP/2 is the latest version of the widely used Hypertext Transfer Protocol (HTTP), which has a lot of performance gains when compared to older versions.
- Newly added eventÂ
ApplicationStartedEvent
:Â AnApplicationStartedEvent
will be sent right after the application context is refreshed but before any command line runners run.ApplicationReadyEvent
 will, however, be sent right after the application context is refreshed and any command-line runners run. This means the application is in a ready state to accept and process requests.
These are the most notable changes, but there are so many more, as with any major release. Other changes can be seen in the Spring Boot 2.0 release notes, found at https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes.
Let's have a look at some of the notable features of Spring Boot 2.0 with some hands-on examples.
Spring Boot allows Builder to create customized Spring Boot application bootstrapping with a tool called SpringApplicationBuilder
. This can be used as follows to customize the Spring Boot application and register a Spring Bean dynamically:
public static void main(String[] args) { new SpringApplicationBuilder(SpringBoot2IntroApplication.class) .bannerMode(Banner.Mode.OFF) .initializers((GenericApplicationContext genericApplicationContext) -> { genericApplicationContext.registerBean ("internet", InternetHealthIndicator.class); })
Â
Â
Â
Â
Â
Â
.run(args); }
In this code, a new instance of SpringApplicationBuilder
is instantiated with a configuration class. By invoking the bannerMode(Banner.Mode.OFF)
 method, the banner shown in the console at the Spring Boot Bootstrap is switched off.Â
By invoking the initializers()
method with a lambda function (learn about lambda functions in the reference documentation at https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) for ApplicationContextInitializer
, the GenericApplicationContext.registerBean
 method is used to register a Spring Bean called internet
and with class type InternetHealthIndicator
.Â
Configuration properties are a great feature of Spring Boot for reading properties with type safety. This section will explain the concept with the following DemoApplicationProperties
 class file:
@ConfigurationProperties(prefix = "demo") public class DemoApplicationProperties { private Integer number; private String username; private String telephoneNumber; private List<String> emailAddresses = Arrays.asList("[email protected]"); private String firstName; private String lastName; private Duration workingTime; // Getters and Setters }
The application.yml
 has the following configuration properties:
demo: number: 10 user-Name: shazin firstName: Shazin lAsTNamE: Sadakath telephone_number: "0094777329939" workingTime: 8h EMAILADDRESSES: - [email protected] - [email protected] addresses: - number: "B 22 2/3" city: Colombo street: "Ramya Place" country: "Sri Lanka" zipCode: "01000" - number: "123" city: Kandy street: "Dalada Weediya" country: "Sri Lanka" zipCode: "01332"
For configuration properties, an application.properties
file also can be used over an application.yml
file. Lately, YML files are becoming famous among developers because they can provide a structure with indentations, the ability to use collections, and so on. Spring Boot supports both at the moment.
Spring Boot 2.0 introduces a new binding API for configuration properties. The most notable change in Spring Boot 2.0 related to configuration property binding is the introduction of a new binding API with the following Address
Plain Old Java Object (POJO):
public class Address { private String number; private String street; private String city; private String country; private String zipCode; // Getters, Setters, Equals, Hashcode }
The following Binder
 fluent API can be used to map properties directly into the Address
POJO.
This code can be written inside any initializing code such as CommandLineRunner
, ApplicationRunner
, and so on. In the application this code is available inside the SpringBoot2IntroApplication.runner
method:
List<Address> addresses = Binder.get(environment) .bind("demo.addresses", Bindable.listOf(Address.class)) .orElseThrow(IllegalStateException::new);
The preceding code will create a Binder
 instance from the given Environment
instance and bind the property for a list of Address
classes. If it fails to bind the property then it will throw IllegalStateException
.
Another notable addition to configuration property binding is exposing the origins of a property. This is a useful feature because many developers have struggled in the past because they had configured the wrong file and ran an application to just see unexpected results. Now, the origin
of a property is shown along with the file, line number, and column number:
"demo.user-Name": { "value":"shazin", "origin":"class path resource [application.yml]:5:14" }
Relaxed property binding rules have the following changes:
- Kebab-case format (lower-case, hyphen-separated) must be used for prefixes. Examples of this are
demo
 andÂdemo-config
. - Property names can use kebab-case, camel-case, or snake-case. Examples of this are
user-Name
,firstName
, andtelephone_number
. - The upper case underscore format that is usually used for environment variables should be followed, where the underscore should only be used to separate parts of the key. The upper case underscore format is usually used for environment variables. The underscore is used to separate parts of the key. An example of this would be
DEMO_ENV_1
.
The complete set of rules for relaxed bindings can be seen in the Spring Boot documentation at https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-relaxed-binding.
Furthermore, environment variables with indices can be mapped to names with array syntax and indices, shown as follows:
DEMO_ENV_1 = demo.env[1] DEMO_ENV_1_2 = demo.env[1][2]
So, the DEMO_ENV_1
environment variable can be read in the application as follows:
System.out.printf("Demo Env 1 : %s\n", environment.getProperty("demo.env[1]"));
Another notable change is the ability to specify time duration in days (d), hours (h), minutes (m), seconds (s), milliseconds (ms), and nanoseconds (ns), which will be correctly mapped to a java.time.Duration
 object in the configuration property. In the example workingTime: 8h
, the property will be mapped to the java.time.Duration workingTime
property correctly. Values such as 8m
, 8s
, 8d
can also be specified to define duration.
In Spring Boot 1.x, in order to write a custom endpoint for Spring Boot Actuator, AbstractEndpoint
 had to be extended and its invoke
method has been overridden with custom logic. Spring Boot Actuator is a production-ready feature for monitoring and managing a Spring Boot application using HTTP endpoints or JMX. Auditing metrics such as health could also be gathered using this feature. Finally, it had to be injected into the Spring Context as a Bean. This endpoint was technologically agnostic, in the sense that it could be invoked using JMX as well as with web requests.
If a custom behavior was required for a particular technology, such as JMX or the web, then AbstractEndpointMvcAdapter
or EndpointMBean
had to be extended respectively and had to be injected as a Spring Bean. This is cumbersome, and Spring Boot 2.0 has introduced technology-specific annotations such as @Endpoint
, @WebEndpoint
, and @JmxEndpoint
; technology-independent operation annotations such as @ReadOperation
,@WriteOperation
, and @DeleteOperation
; and technology-specific extension annotations such as  @EndpointWebExtension
 and @EndpointJmxExtension
, to ease this process.
Note
By default, only the /info
and /health
endpoints are exposed. The management.endpoints.web.exposure.include=*
 property must be set to expose other endpoints, including custom ones.
The @ReadOperation
 annotation will expose the Getter
for the custom endpoint and the @WriteOperation
 will expose the Setter
for the custom endpoint. The endpoint will be mapped under the http://<host>:<port>/actuator/custom
 URL (the default host is localhost
, and the default port is 8080
unless configured otherwise) and also exposed as a JMX Management bean:
@Component @Endpoint(id = "custom") public class CustomEndpoint { private final static Logger LOGGER = LoggerFactory.getLogger(CustomEndpoint.class); @ReadOperation public String get() { return "Custom Endpoint"; } @WriteOperation public void set(String message) { LOGGER.info("Custom Endpoint Message {}", message); } }
The following extension class, which uses @EndpointWebExtension
to extendCustomEndpoint
for custom behavior for web technology and for JMX technology, will not be changed:
@Component @EndpointWebExtension(endpoint = CustomEndpoint.class) public class CustomEndpointWebExtension { ... @ReadOperation public WebEndpointResponse<String> getWeb() { ... return new WebEndpointResponse<>("Custom Web Extension Hello, World!", 200); } }
The @EndpointWebExtension
annotation will make the CustomEndpointWebExtension
a web extension for CustomEndpoint
with its endpoint property. The method with the @ReadOperation
annotation will be the overridden Getter
. Accessing http://<host>:<port>/actuator/custom
 (the default host is localhost
, and the default port is 8080
unless configured otherwise) and a URL using a browser will prompt for the username (specify sysuser
) and password (specify password
) and when logged in will return the following:
Custom Web Extension Hello, World!
Running the Spring Boot application with the following VM arguments will enable it to be connected using jconsole
remotely, and the exposed CustomEndpoint
 JMX Bean can be accessed using monitoring and management tools such as jconsole
, which is shipped with the JDK installation:
-Djavax.management.builder.initial= -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8855 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Run jconsole
with the following command:
$ jconsole
Making a remote process connected with it to<host>:8855
will list all the MBeans
from the Spring Boot application under MBeans
tab. When the Custom.get
operation is executed from jconsole
it will show the return from CustomEndpoint.get
 as expected, as shown in the following screenshot:

With the introduction of Micrometer to Spring Boot Actuator in Spring Boot 2.0, metrics can be customized easily. The following code snippet from CustomEndpointWebExtension
 shows how to make use of io.micrometer.core.instrument.MeterRegistry
 to maintain a counter with the name custom.endpoint.calls
, which will be incremented every time CustomEndpointWebExtension
 is invoked:
public static final String CUSTOM_ENDPOINT_CALLS = "custom.endpoint.calls"; private final MeterRegistry meterRegistry; public CustomEndpointWebExtension(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @ReadOperation public WebEndpointResponse<String> getWeb() { meterRegistry.counter(CUSTOM_ENDPOINT_CALLS).increment(); return new WebEndpointResponse<>("Custom Web Extension Hello, World!", 200); }
The preceding code injects MeterRegistry
from the Micrometer Framework, which is used to create and retrieve a counter named custom.endpoint.calls
 and increment it during each read operation of the custom web endpoint extension.
This metric will be available under the http://<host>:<port>/actuator/metrics/custom.endpoint.calls
 URL, which will show a result similar to the following:
{ "name":"custom.endpoint.calls", "measurements":[ { "statistic":"COUNT", "value":3.0 } ], "availableTags":[] }
Spring Boot Actuator's health endpoint is really helpful for checking the status of Spring Boot application and dependent systems such as databases, message queues, and so on. Spring Boot ships out of the box with many standard HealthIndicator
implementations such as DiskSpaceHealthIndicator
, DataSourceHealthIndicator
, and MailHealthIndicator
, which can all be used in Spring Boot applications with Spring Boot Actuator. Furthermore, custom health indicators can also be implemented if required:
public class InternetHealthIndicator implements HealthIndicator { private static final Logger LOGGER = LoggerFactory.getLogger(InternetHealthIndicator.class); public static final String UNIVERAL_INTERNET_CONNECTIVITY_CHECKING_URL = "https://www.google.com"; private final RestTemplate restTemplate; public InternetHealthIndicator(RestTemplateBuilder restTemplateBuilder) { this.restTemplate = restTemplateBuilder.build(); } @Override public Health health() { try { ResponseEntity<String> response = restTemplate.getForEntity(UNIVERAL_INTERNET_CONNECTIVITY_CHECKING_URL, String.class); LOGGER.info("Internet Health Response Code {}", response.getStatusCode()); if (response.getStatusCode().is2xxSuccessful()) { return Health.up().build(); } } catch(Exception e) { LOGGER.error("Error occurred while checking internet connectivity", e); return Health.down(e).build(); } return Health.down().build(); } }
The preceding InternetHealthIndicator
is intended to show the status of internet connectivity from within Spring Boot applications to the outside world. It will send a request to www.google.com to check whether it sends a successful HTTP response code, and based on that the health status of this indicator will be set to up or down. This was injected as a Spring Bean using an ApplicationContextInitializer
earlier. Invoking the http://<host>:<port>/actuator/health
 URL will return the internet status as in the following:
{ "status":"UP", "details":{ "internet":{ "status":"UP" }, "diskSpace":{ "status":"UP", "details":{ "total":399268376576, "free":232285409280, "threshold":10485760 } } } }
HTTP was invented by Tim Berners-Lee in 1989 while he was working at CERN. It was designed as a way to share scientific findings among coworkers and is almost three decades old. When HTTP was invented, it was never intended to be the backbone of today's low-latency, high-traffic web, used by millions if not billions of people. So HTTP 1-and HTTP 1.1-based web applications had to have a lot of workarounds to cater to the high demands of the modern web. The following are some of those workarounds:
- Concurrent resources are download by the browser since HTTP 1.x can download only one resource at a time, and Domain Sharding is used to tackle limitations on the maximum number of connections per domain
- Combining multiple resources such as CSS/Javascript files together with complex server-side logic and downloading them all in one go
- Multiple image sprites in a single resource to reduce the number of image file downloads
- Inlining static resources in an HTML file itself
But HTTP/2 is designed from the ground up to tackle these pain points. Compared to HTTP 1.x, HTTP/2 doesn't use text to communicate between the client and server. It uses binary data frames, which makes it much more efficient and reduces the text-to-binary and binary-to-text conversion overhead in the servers. Furthermore, it has the following features introduced:
- HTTP/2 multiplexing: This multiplexing feature allows opening one connection to a server and downloading multiple resources using that connection:

- HTTP/2 push: This will send resources to clients even before resources are requested:

Â
- HTTP/2 header compression: Eliminates the repeating of the same headers across multiple requests by maintaining an HTTP header table, thus reducing request bandwidth
Spring Boot 2 supports HTTP/2 out of the box for server Undertow, and, with minor dependencies at https://docs.spring.io/spring-boot/docs/2.0.x-SNAPSHOT/reference/htmlsingle/#howto-configure-http2, also supports Tomcat and Jetty servers. But Spring Boot 2 doesn't support the clear text version of HTTP/2, so Secure Socket Layer (SSL) is a must. It requires the following dependencies in pom.xml
:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> ... </dependencies>
The configuration properties in application.yml
 configure both SSL and HTTP/2:
server: port: 8443 ssl: key-store: keystore.p12 key-store-password: sslcert123 keyStoreType: PKCS12 keyAlias: sslcert http2: enabled: true
In this configuration SSL key-store
, key-store-password
, keyStoreType
, and keyAlias
are configured along with the port for HTTPs. The key was generated using keytool
, which is a utility shipped with the JDK release with the following command, and fills in the necessary details when prompted by the utility tool:
$ keytool -genkey -alias sslcert -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Note
This key-store
is not recommended for production as it is not generated by a Trusted Certificate Authority. A proper SSL Certificate must be used in production.
Now when the https://<localhost>:8443/actuator/custom
URL is accessed it will be served over HTTP/2.
Spring Boot 2.0 has introduced updated support for Spring Security with Spring Framework 5.0 and Reactive support for Spring Security, providing simplified default configurations and ease of customization for Spring Security. As opposed to having multiple auto-configurations for Spring Security, Spring Boot 2.0 has introduced a single behavior that can be overridden easily and can be customized easily with a WebSecurityConfigurerAdapter
such as the following:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic().and() .authorizeRequests() .requestMatchers(EndpointRequest.to("info", "health")).permitAll() .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("SYSTEM") .antMatchers("/**").hasRole("USER"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .passwordEncoder(new MessageDigestPasswordEncoder("SHA-256")) .withUser("user") .password("5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8") .roles("USER") .and() .withUser("sysuser") .password("5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8") .roles("SYSTEM"); } }
One thing to note here is the introduction of the EndpointRequest
 helper class, which makes it easier to protect endpoints.
Spring Boot is a highly active project with contributors from all around the World. At the time of writing, the Spring Boot 2.1.0 milestone is set and is under active development. The following are some of the features proposed for that Spring Boot minor-version release:
- Support for embedding Tomcat 9: Tomcat 9 has introduced a lot of features, but Spring Boot 2.0 still only supports up to Tomcat 8 by default. With this support, Spring Boot 2.0 will be able to offer features such as Servlet 4.0 API, JSP 2.4, WebSocket 2.0, and so on.
- Auto-configuration of JettyMetrics: Micrometer has metrics support for Jetty, which is planned to be included in the next release of Spring Boot 2.0.
- Support for embedding Undertow 2.0: Undertow 2.0 has a lot of features, such as Servlet 4.0, but is not yet supported by Spring Boot 2.0.
- Support for Hibernate 5.3.0 and JPA 2.2: Hibernate 5.3.0 and JPA 2.2 are the latest releases for the persistence layer, which needs to be incorporated into Spring Boot 2.0.
- Actuator endpoint for listing and clearing cache: The actuator endpoint is intended to return caches per context and provides a
delete
operation to clear the cache. - Allowing
@ConfigurationProperties
binding on interfaces: At the moment only a class can be used to bind properties from a configuration properties file with a@ConfigurationProperties
annotation. This feature will allow interfaces with methods with property names to be mapped to their corresponding property. - Having consistent auto-configuration behavior for default connection of data sources: Currently, behavior for default connection auto-configurations differs from data sources as such as MongoDB, Couchbase, and so on. This proposed change will make it consistent.
However, these enhancements and features are still under active evaluation and debate and can be further improved or reduced based on the collective decisions of the Spring Boot developer community.
Spring Boot 2.0 is a major release; it will require care when migrating from Spring Boot 1.x, as a lot has changed. Migration is unavoidable, as existing applications require the use of new features and enhancements available in the latest Spring Boot 2.0 release. The official migration guide can be read at https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide and in this section, the most notable migration tips will be discussed.
Spring Boot 2.0 doesn't support Java 6 or Java 7, which are still widely used in many production environments. So the first thing that needs to be done is to upgrade both development environments and runtime environments to at least Java 8 or above.Â
Since Java 9 was a major release and has one of the most complex enhancement modifications made to Java since its inception (the modular system), special care needs to be taken when running the Spring Boot 2.0 application on it. The following tips will help you get started.
The following exception can be expected as soon as a Spring Boot 2.0 application is run on Java 9:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
This is because Hibernate requires JAXB, which is not shipped by default in Java 9. The following dependency needs to be added in pom.xml
to include it:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency>
Instead, you can add the java.xml.bind
module to Java 9 directly to get rid of this exception.
Java 9 requires AspectJ version 1.9 (currently in Release Candidate version) if JDK weaving of classes is required. Spring Boot 2.0, however, can work with the lower version 1.8 that is shipped by default.
Apache Cassandra drivers that run on Spring Boot 2.0 are not fully supported by Java 9 at the time of writing this book, so if a Spring Boot 2.0 application uses these then it must be properly tested. The issue can be followed at https://github.com/spring-projects/spring-boot/issues/10453 for more updates.
Maven Surefire Plugin version 2.20.1 has re-introduced a bug that was fixed on other Java versions and only raised when running tests on Java 9. In order to fix this, the Maven Surefire Plugin has to be downgraded to 2.20.0 or the java.se.ee
module needs to be excluded from the runtime while running tests.
Spring Boot 2.0 by default uses and supports Spring Framework 5.0. Thus, any change to it will affect migration to Spring Boot 2.0. Some notable changes are explained in the following topics.
The @CrossOrigin
 annotations property allowCredentials
now has the default value false
. This means that it needs to be explicitly set if cookies or authentication are required.Â
The following packages, classes, and methods are no longer supported in the Spring Framework 5.0 release:
- The
beans.factory.access
package, including the classSpringBeanAutowiringInterceptor
. - The
jdbc.support.nativejdbc
package, which is replaced by JDBC 4 implementation. - The
mock.staticmock
package, with whichÂAnnotationDrivenStaticEntityMockingControl
 is no longer supported. - The
web.views.tiles2
package, with the minimum version requirement for tiles being version3
. - The
orm.hibernate3/hibernate4
packages, with the minimum version requirement for Hibernate being version5
. - Most of the deprecated classes in the previous version have been removed.
- Some methods in JSP Standard Tag Library (JSTL) have been removed. For example,
FormTag
commandName
is no longer available.
A lot of configuration properties have been renamed/replaced from Spring Boot 1.x to Spring Boot 2.0. So these changes must be incorporated in the application.yml/application.properties
file to do a successful migration. To ease this process, Spring Boot has released the spring-boot-properties-migrator
properties migrator, which can be used in the Maven configuration as follows:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope> </dependency>
When this dependency is used, it will analyze the application environment, print out any diagnostics at startup, and even temporarily migrate properties at runtime.
With the introduction of Reactive Web Programming out of the box in Spring Boot 2.0, there needs to be a differentiation between properties for a servlet stack and properties for a reactive stack, so that previous properties such as server.*
, which was related to the server ServletContext path, is not changed toserver.servlet.*
 , avoiding verbosity in property naming.Â
In Spring Boot 2.0 the file extension for the mustache template engine has been changed from .html
 to .mustache
. With the spring.mustache.suffix
configuration property this behavior can be overridden if required.
The following changes have been introduced in the Spring Boot Actuator configuration properties in Spring Boot 2.0:
endpoints.*
 properties have been moved undermanagement.*
management.*
 properties have been moved underÂmanagement.server.*
endpoints.<id>.*
 properties have been moved undermanagement.endpoint.<id>.*
- Shutdown endpoint must be explicitly enabled by setting theÂ
management.endpoint.shutdown.enabled
 configuration property totrue
These changes have the potential to break existing code, and so must be changed accordingly when migrating.
Now, the /actuator
path contains all Spring Boot Actuator-related endpoints. In order to get the previous version's behavior, the management.endpoints.web.base-path=/
configuration property needs to be set. Another change is the addition of a new purpose formanagement.server.servlet.context-path
, which is the counterpart of server.servlet.context-path
 related to Spring Boot Actuator endpoints.
As an example, if management.server.servlet.context-path=/actuator
 is set, along with management.endpoints.web.base-path=/application
, then the endpoints will be accessible under the /actuator/application/<endpoint>
path.
The following Spring Boot Actuator endpoints have been changed:
/autoconfig
has been renamed to/conditions
/trace
has been renamed to/httptrace
Applications depending on these endpoints need to be changed to use the renamed endpoints.
EmbeddedServletContainer
is changed to WebServer
. Also, the org.springframework.boot.context.embedded
package is refactored to org.springframework.boot.web.embedded
. If TomcatEmbeddedServletContainerFactory
was used to configure an embedded Tomcat with a custom port in an application as in the following, then it will need to be changed:
@Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(9090); tomcat.addAdditionalTomcatConnectors(connector); return tomcat; }
It must be changed to use TomcatServletWebServerFactory
instead, as in the following:
@Bean public TomcatServletWebServerFactory webServer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(9090); return tomcat; }
The default behavior of map extensions such as .json
and .xml
to existing controller request mappings has changed in Spring Boot 2.0. Consider the following URL mapping:
@GetMapping("/users")
If it is expected to cater to the /users.json
URL in a Spring Boot 1.x application, then it won't be supported in Spring Boot 2.0. This means new mappings need to be added as necessary.
The default dispatcher type for the servlet filter in Spring Boot 2.0 is DispatcherType.REQUEST
. This is changed to be in line with the default in the servlet specification. If other dispatcher types are required then a FilterRegistrationBean
must be used to register the filter.
Spring Boot 1.x had the transitive dependencyspring-boot-starter-web
whenever one of the following template engine starters was used:
spring-boot-starter-freemarker
spring-boot-starter-thymeleaf
spring-boot-starter-mustache
This was done because Spring Web MVC was running on top of the Servlet API, which is the only web application framework that was available at that time.
Now, with the introduction of the Spring Reactive Web starter spring-boot-starter-webflux
, which is completely independent of the Servlet API, transitive dependencies from those template engine starters have been removed. This means that, when a template engine starter dependency is added, a developer needs to manually add a dependency to either Spring Web MVC starter or Spring Web Flux starter based on the requirement.
Spring Boot 2.0 uses CGLIB as the default proxying strategy including for aspect-oriented programming (AOP). If proxy based proxying is required, the following configuration property needs to be set:
spring.aop.proxy-target-class=false.
With Spring Boot 2.0, the spring.config.location
configuration will no longer append to the list of configurations; instead, it will replace it. So, if append logic is required, then spring.config.additional-location
must be used.
With Spring Boot 2.0, Jackson's configuration was modified to write JSR-310 dates as ISO-8601 strings. For its previous behavior, the property spring.jackson.serialization.write-dates-as-timestamps=true
needs to be set.
The separate security auto-configuration for actuators has been removed in Spring Boot 2.0; thus, management.security.*
properties are no longer supported. The endpoints.<id>.sensitive
flag for each endpoint is no longer available, and if an application is dependent on this behavior then it must use a custom configuration for Spring Security to permit or restrict access to those endpoints.Â
With Spring Boot 2.0, the default connection pool for JPA has been changed from Tomcat to HikariCP. Thus it is no longer required to use the configuration property spring.datasource.type
as an override to use HikariCP. Using the following dependency will by default use HikariCP:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
With Spring Boot 2.0, the default basic DataSource initialization is only enabled for embedded databases and will be disabled as soon as a production database is used. The configuration property spring.datasource.initialization-mode
(with values always
or never
), which replaces the old spring.datasource.initialize
configuration property, can be used for more control.Â
The default behavior for embedded databases used with a schema manager such as Liquibase, Flyway, and so on will be dropping existing tables and creating a new one, which is similar to create-drop
for the configuration property spring.jpa.hibernate.ddl-auto
 .If no schema manager is used then the default behavior is to do nothing, which is similar to setting none
 for the aforementioned configuration property.
The following test annotations are no longer supported for Mockito 1.x:
@MockBean
@SpyBean
If testing needs to be done using the aforementioned annotations then Spring Boot 2.0 spring-boot-starter-test
must be used or Mockito 2.x must be used explicitly.Â
There are some Spring Security-related changes made for Spring Boot 2.0's release, which need to be incorporated when migrating. Some of the most notable ones are explained in the following sections.
Spring Security has changed its auto-configuration strategy to make use of defaults in most cases instead of enabling multiple configuration options. Notable cases are when Spring Security authorization with content negotiation is used.
The OAuth2 project is now part of the Spring Security core project and released out of the box. Thus dependencies for OAuth2 will not be maintained separately as of Spring Security 5.0. If a Spring Boot application makes use of a non-migrated feature then dependencies for those need to be added explicitly.
Some features that were available in Spring Boot 1.x but are no longer supported in Spring Boot 2.0 are as follows:
- Disabled CRaSH supportâSpring Boot 1.x had an integrated Java shell that was used to SSHÂ and Telnet in a Spring Boot application. This is no longer available and theÂ
spring-boot-starter-remote-shell
 dependency can no longer provide support in monitoring and manage Spring Boot applications. - Removed auto-configuration support for Spring Mobile.
- Removed auto-configuration support for Spring Social.
- Removed dependency management support forÂ
commons-digester
.
Congratulations on completing the first chapter. This chapter talked about what Spring Boot is, and explained its unique characteristics in depth by talking about Spring Boot's standalone, production-grade, flexible, and extensible capabilities in detail with examples.
Also, it talked about how to get started with Spring Boot application development by going through the anatomy of a Spring Boot application. It explained what makes a Spring Boot application different from a standard Maven Java application. Also, it talked about the ways a Spring Boot application can be run.
Next, it talked about what has changed from Spring Boot 1.x to Spring Boot 2.0, as it is a major version release, and how to successfully migrate from Spring Boot 1.x to Spring Boot 2.0 by going through each change and explaining how it affects an existing Spring Boot application. It also covered how to mitigate any adverse effects successfully without breaking the application.
Furthermore, it talked about what is in the pipeline for the next minor release of Spring Boot 2.0. These are enhancements that are proposed and discussed by the Spring Boot community, which they deem necessary for the next minor release. These features, along with more features, enhancements, and bug fixes, can be expected in the next minor release, Spring Boot 2.1.0.
This chapter has set the pace for coming chapters, which contain more exciting, hands-on Spring Boot 2.0 applications. The contents of this chapter will help greatly in upcoming chapters when it comes to understanding what makes a Spring Boot application work. This chapter also touched on different parts of the Spring Framework ecosystem such as Spring Security, Spring Data JPA, and so on, which will be covered in detail in coming chapters. This chapter has enabled us to write Spring Boot 2.0 applications that just run easily and effectively.
Please answer the following questions to see whether you have successfully mastered this chapter:
- What is Spring Boot?
- What is the bare minimum code to start a Spring Boot application?
- What is the minimum platform required to run a Spring Boot 2.0 application?
- What is HTTP/2?
- What is the default dispatcher type for a Spring Boot 2.0 servlet filter?
- What is the next minor release version of Spring Boot 2.0?
- What is the name of the default connection pool framework for a Spring Boot 2.0 application with the JPA starter?
In order to improve your knowledge of Java and Spring Boot, the following books are recommended. They will be helpful in the coming chapters:
- Learning Reactive Programming with Java 8: https://www.packtpub.com/application-development/learning-reactive-programming-java-8
- Learning Spring Boot 2.0Â â Second Edition:Â https://www.packtpub.com/application-development/learning-spring-boot-20-second-edition