SpringBoot 2.1.2 Keys
SpringBoot 2.1.2 Keys
SpringBoot 2.1.2 Keys
Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you
can run. We take an opinionated view of the Spring platform and third-party libraries, so that you can get
started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
Spring Boot 2.1.2.RELEASE requires Java 8 and is compatible up to Java 11 (included). Spring
Framework 5.1.4.RELEASE or above is also required.
Containers
You can also deploy Spring Boot applications to any Servlet 3.1+ compatible container.
Building
Spring Boot dependencies use the org.springframework.boot groupId. Typically, your Maven
POM file inherits from the spring-boot-starter-parent project and declares dependencies to one
or more “Starters”. Spring Boot also provides an optional Maven plugin to create executable jars.
The @RequestMapping annotation provides “routing” information. It tells Spring that any HTTP
request with the / path should be mapped to the home method. The@RestController annotation
tells Spring to render the resulting string directly back to the caller.
The @RestController and @RequestMapping annotations are Spring MVC annotations. (They are
not specific to Spring Boot.)
Auto-configuration is designed to work well with “Starters”, but the two concepts are not directly tied. You
are free to pick and choose jar dependencies outside of the starters. Spring Boot still does its best to
auto-configure your application.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
If you use the Spring Boot starter parent pom, you need to add only the
plugin. There is no need to configure it unless you want to change the
settings defined in the parent.
Starters
Starters are a set of convenient dependency descriptors that you can include in your application. You get
a one-stop shop for all the Spring and related technologies that you need without having to hunt through
sample code and copy-paste loads of dependency descriptors.
The starters contain a lot of the dependencies that you need to get a project up and running quickly and
with a consistent, supported set of managed transitive dependencies.
The following application starters are provided by Spring Boot under the
org.springframework.boot group:
In addition to the application starters, the following starters can be used to add production
ready features:
actuator
Finally, Spring Boot also includes the following starters that can be used if you want to
exclude or swap specific technical facets:
spring-boot- Starter for using Jetty as the embedded servlet container. An Pom
starter-jetty alternative to spring-boot-starter-tomcat
spring-boot- Starter for using Log4j2 for logging. An alternative to spring- Pom
starter-log4j2 boot-starter-logging
spring-boot- Starter for logging using Logback. Default logging starter Pom
starter-logging
spring-boot- Starter for using Reactor Netty as the embedded reactive HTTP Pom
starter-reactor- server.
netty
spring-boot- Starter for using Tomcat as the embedded servlet container. Pom
starter-tomcat Default servlet container starter used by spring-boot-
starter-web
spring-boot- Starter for using Undertow as the embedded servlet container. An Pom
starter-undertow alternative to spring-boot-starter-tomcat
Structuring Your Code
Spring Boot does not require any specific code layout to work. However, there are some
best practices that help.
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
The Application.java file would declare the main method, along with the basic
@SpringBootApplication, as follows:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
}
Configuration Classes
Spring Boot favors Java-based configuration. Although it is possible to use
SpringApplication with XML sources, we generally recommend that your primary
source be a single @Configuration class. Usually the class that defines the main
method is a good candidate as the primary @Configuration.
Auto-configuration
Spring Boot auto-configuration attempts to automatically configure your Spring application
based on the jar dependencies that you have added. For example, if HSQLDBis on your
classpath, and you have not manually configured any database connection beans, then
Spring Boot auto-configures an in-memory database.
If you need to find out what auto-configuration is currently being applied, and why, start your
application with the --debug switch. Doing so enables debug logs for a selection of core
loggers and logs a conditions report to the console.
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
If the class is not on the classpath, you can use the excludeName attribute of the
annotation and specify the fully qualified name instead. Finally, you can also control the list
of auto-configuration classes to exclude by using the
spring.autoconfigure.exclude property.
The following example shows a @Service Bean that uses constructor injection to obtain a
required RiskAssessor bean:
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
If a bean has one constructor, you can omit the @Autowired, as shown in the following
example:
@Service
public class DatabaseAccountService implements AccountService {
// ...
}
Notice how using constructor injection lets the riskAssessor
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
and @ComponentScan.
None of these features are mandatory and you may choose to replace this single
annotation by any of the features that it enables. For instance, you may not want to
use component scan in your application:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import
org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {
In this example, Application is just like any other Spring Boot application except
that @Component-annotated classes are not detected automatically and the user-
You might also want to use the JAVA_OPTS operating system environment variable, as
shown in the following example:
$ export JAVA_OPTS=-Xmx1024m
Developer Tools
Spring Boot includes an additional set of tools that can make the application development
experience a little more pleasant. The spring-boot-devtools module can be included
in any project to provide additional development-time features. To include devtools support,
add the module dependency to your build, as shown in the following listings for Maven and
Gradle:
Maven.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle.
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
Developer tools are automatically disabled when running a fully
packaged application. If your application is launched from java
SpringApplication
The SpringApplication class provides a convenient way to bootstrap a Spring
application that is started from a main() method. In many situations, you can delegate to
the static SpringApplication.run method, as shown in the following example:
Startup Failure
If your application fails to start, registered FailureAnalyzers get a chance to provide a
dedicated error message and a concrete action to fix the problem. For instance, if you start a
web application on port 8080 and that port is already in use, you should see something
similar to the following message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure
this application to listen on another port.
If no failure analyzers are able to handle the exception, you can still display the full
conditions report to better understand what went wrong. To do so, you need to enable the
debug property or enable DEBUG logging for
org.springframework.boot.autoconfigure.logging.ConditionEvalua
tionReportLoggingListener.
For instance, if you are running your application by using java -jar, you can enable the
debug property as follows:
Inside your banner.txt file, you can use any of the following placeholders:
Variable Description
example (v1.0).
You can also use the spring.main.banner-mode property to determine if the banner
has to be printed on System.out (console), sent to the configured logger (log), or not
produced at all (off).
The printed banner is registered as a singleton bean under the following name:
springBootBanner.
YAML maps off to false, so be sure to add quotes if you
want to disable the banner in your application, as shown in the
following example:
spring:
main:
banner-mode: "off"
In my case what i did is create a txt file in the resources folder and set the property in spring
spring.banner.location = classpath:/banner.txt
SpringApplicationBuilder.listeners(…) method.
org.springframework.context.ApplicationListener=com.exampl
e.project.MyListener
Application events are sent in the following order, as your application runs:
You often need not use application events, but it can be handy
to know that they exist. Internally, Spring Boot uses events to
handle a variety of tasks.
Application events are sent by using Spring Framework’s event publishing mechanism. Part
of this mechanism ensures that an event published to the listeners in a child context is also
published to the listeners in any ancestor contexts. As a result of this, if your application
uses a hierarchy of SpringApplication instances, a listener may receive multiple
instances of the same type of application event.
To allow your listener to distinguish between an event for its context and an event for a
descendant context, it should request that its application context is injected and then
compare the injected context with the context of the event. The context can be injected by
implementing ApplicationContextAware or, if the listener is a bean, by using
@Autowired.
Web Environment
A SpringApplication attempts to create the right type of ApplicationContext on
your behalf. The algorithm used to determine a WebApplicationType is fairly simple:
This means that if you are using Spring MVC and the new WebClient from Spring
WebFlux in the same application, Spring MVC will be used by default. You can override that
easily by calling setWebApplicationType(WebApplicationType).
It is also possible to take complete control of the ApplicationContext type that is used
by calling setApplicationContextClass(…).
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true,
files=["logfile.txt"]
}
@Component
public class MyBean implements CommandLineRunner {
Admin Features
It is possible to enable admin-related features for the application by specifying the
spring.application.admin.enabled property. This exposes
theSpringApplicationAdminMXBean on the platform MBeanServer. You could
use this feature to administer your Spring Boot application remotely. This feature could also
be useful for any service wrapper implementation.
Caution
Externalized Configuration
Spring Boot lets you externalize your configuration so that you can work with the same
application code in different environments. You can use properties files, YAML files,
environment variables, and command-line arguments to externalize configuration. Property
values can be injected directly into your beans by using the @Valueannotation, accessed
through Spring’s Environment abstraction, or be bound to structured objects through
@ConfigurationProperties.
Spring Boot uses a very particular PropertySource order that is designed to allow
sensible overriding of values. Properties are considered in the following order:
To provide a concrete example, suppose you develop a @Component that uses a name
property, as shown in the following example:
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
On your application classpath (for example, inside your jar) you can have an
application.properties file that provides a sensible default property value for
name. When running in a new environment, an application.properties file can be
provided outside of your jar that overrides the name. For one-off testing, you can launch with
a specific command line switch (for example, java -jar app.jar
--name="Spring").
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java
-jar myapp.jar
You can also supply the JSON by using a command line argument, as shown in
the following example:
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
The random.int* syntax is OPEN value (,max) CLOSE where the OPEN,CLOSE
are any character and value,max are integers. If max is provided, then value is the
minimum value and max is the maximum value (exclusive).
If you do not want command line properties to be added to the Environment, you can
disable them by using
SpringApplication.setAddCommandLineProperties(false).
Application Property Files
SpringApplication loads properties from application.properties files in the
following locations and adds them to the Spring Environment:
The list is ordered by precedence (properties defined in locations higher in the list override
those defined in lower locations).
If you do not like application.properties as the configuration file name, you can
switch to another file name by specifying a spring.config.name environment property.
You can also refer to an explicit location by using the spring.config.location
environment property (which is a comma-separated list of directory locations or file paths).
The following example shows how to specify a different file name:
Profile-specific Properties
In addition to application.properties files, profile-specific properties can also be
defined by using the following naming convention: application-
{profile}.properties. The Environment has a set of default profiles (by default,
[default]) that are used if no active profiles are set. In other words, if no profiles are
explicitly activated, then properties from application-default.properties are
loaded.
If several profiles are specified, a last-wins strategy applies. For example, profiles specified
by the spring.profiles.active property are added after those configured through
the SpringApplication API and therefore take precedence.
Placeholders in Properties
The values in application.properties are filtered through the existing
Environment when they are used, so you can refer back to previously defined values (for
example, from System properties).
app.name=MyApp
app.description=${app.name} is a Spring Boot application
Loading YAML
Spring Framework provides two convenient classes that can be used to load YAML
documents. The YamlPropertiesFactoryBean loads YAML as Properties and
the YamlMapFactoryBean loads YAML as a Map.
environments:
dev:
url: http://dev.example.com
name: Developer Setup
prod:
url: http://another.example.com
name: My Cool App
environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App
YAML lists are represented as property keys with [index] dereferencers. For example,
consider the following YAML:
my:
servers:
- dev.example.com
- another.example.com
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
To bind to properties like that by using Spring Boot’s Binder utilities (which is what
@ConfigurationProperties does), you need to have a property in the target bean of
type java.util.List (or Set) and you either need to provide a setter or initialize it with
a mutable value. For example, the following example binds to the properties shown
previously:
@ConfigurationProperties(prefix="my")
public class Config {
YAML Shortcomings
YAML files cannot be loaded by using the @PropertySource annotation. So, in the case
that you need to load values that way, you need to use a properties file.
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import
org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("acme")
public class AcmeProperties {
}
}
@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {
This style of configuration works particularly well with the SpringApplication external
YAML configuration, as shown in the following example:
# application.yml
acme:
remote-address: 192.168.1.1
security:
username: admin
roles:
- USER
- ADMIN
To work with @ConfigurationProperties beans, you can inject them in the same
way as any other bean, as shown in the following example:
@Service
public class MyService {
@Autowired
public MyService(AcmeProperties properties) {
this.properties = properties;
}
//...
@PostConstruct
public void openConnection() {
Server server = new Server(this.properties.getRemoteAddress());
// ...
}
Third-party Configuration
As well as using @ConfigurationProperties to annotate a class, you can also use it
on public @Bean methods. Doing so can be particularly useful when you want to bind
properties to third-party components that are outside of your control.
@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
...
}
Any property defined with the another prefix is mapped onto that AnotherComponent
bean in manner similar to the preceding AcmeProperties example.
Relaxed Binding
Spring Boot uses some relaxed rules for binding Environment properties to
@ConfigurationProperties beans, so there does not need to be an exact match
between the Environment property name and the bean property name. Common
examples where this is useful include dash-separated environment properties (for example,
context-path binds to contextPath), and capitalized environment properties (for
example, PORT binds to port).
@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {
In the preceding example, the following properties names can all be used:
Property Note
acme.my- Kebab case, which is recommended for use in
project.person. .properties and .yml files.
first-name
ame
When binding to Map properties, if the key contains anything other than lowercase alpha-
numeric characters or -, you need to use the bracket notation so that the original value is
preserved. If the key is not surrounded by [], any characters that are not alpha-numeric or
- are removed. For example, consider binding the following properties to a Map:
acme:
map:
"[/key1]": value1
"[/key2]": value2
/key3: value3
The properties above will bind to a Map with /key1, /key2 and key3 as the keys in the
map.
@ConfigurationProperties Validation
Spring Boot attempts to validate @ConfigurationProperties classes whenever they
are annotated with Spring’s @Validated annotation. You can use JSR-303
javax.validation constraint annotations directly on your configuration class. To do so,
ensure that a compliant JSR-303 implementation is on your classpath and then add
constraint annotations to your fields, as shown in the following example:
@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {
@NotNull
private InetAddress remoteAddress;
You can also add a custom Spring Validator by creating a bean definition called
configurationPropertiesValidator. The @Bean method should be declared static. The
configuration properties validator is created very early in the application’s lifecycle, and declaring the
@Bean method as static lets the bean be created without having to instantiate the @Configuration
class. Doing so avoids any problems that may be caused by early instantiation. There is a property
validation samplethat shows how to set things up.
Finally, while you can write a SpEL expression in @Value, such expressions are not
processed from application property files.
Profiles
Spring Profiles provide a way to segregate parts of your application configuration and make
it be available only in certain environments. Any @Component or @Configuration can
be marked with @Profile to limit when it is loaded, as shown in the following example:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
spring.profiles.active=dev,hsqldb
You could also specify it on the command line by using the following switch:
--spring.profiles.active=dev,hsqldb.
By default, if you use the “Starters”, Logback is used for logging. Appropriate Logback
routing is also included to ensure that dependent libraries that use Java Util Logging,
Commons Logging, Log4J, or SLF4J all work correctly.
Log Format
The default log output from Spring Boot resembles the following example:
Console Output
The default log configuration echoes messages to the console as they are written. By
default, ERROR-level, WARN-level, and INFO-level messages are logged. You can also
enable a “debug” mode by starting your application with a --debug flag.
application.properties.
When the debug mode is enabled, a selection of core loggers (embedded container,
Hibernate, and Spring Boot) are configured to output more information. Enabling the debug
mode does not configure your application to log all messages with DEBUG level.
Alternatively, you can enable a “trace” mode by starting your application with a --trace
flag (or trace=true in your application.properties). Doing so enables trace
logging for a selection of core loggers (embedded container, Hibernate schema generation,
and the whole Spring portfolio).
File Output
By default, Spring Boot logs only to the console and does not write log files. If you want to
write log files in addition to the console output, you need to set alogging.file or
logging.path property (for example, in your application.properties).
The following table shows how the logging.* properties can be used together:
logging.file
logging.path
Example Description
Spe (non m Writes to the specified log file. Names can be an exact
cific e) y location or relative to the current directory.
file .
l
o
g
Log files rotate when they reach 10 MB and, as with console output, ERROR-level, WARN-
level, and INFO-level messages are logged by default. Size limits can be changed using the
logging.file.max-size property. Previously rotated files are archived indefinitely
unless the logging.file.max-history property has been set.
Log Levels
All the supported logging systems can have the logger levels set in the Spring
Environment (for example, in application.properties) by
usinglogging.level.<logger-name>=<level> where level is one of TRACE,
DEBUG, INFO, WARN, ERROR, FATAL, or OFF. The root logger can be configured by
using logging.level.root.
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
You can force Spring Boot to use a particular logging system by using the
org.springframework.boot.logging.LoggingSystem system property. The
value should be the fully qualified class name of a LoggingSystem implementation. You
can also disable Spring Boot’s logging configuration entirely by using a value of none.
There are known classloading issues with Java Util Logging that
cause problems when running from an 'executable jar'. We
recommend that you avoid it when running from an 'executable
jar' if at all possible.
To help with the customization, some other properties are transferred from the Spring
Environment to System properties, as described in the following table:
conversion- _WORD
word
logging.patter LOG_LEVEL_PA
n.level TTERN
The format to use when rendering the
log level (default %5p). (Only supported
with the default Logback setup.)
All the supported logging systems can consult System properties when parsing their
configuration files. See the default configurations in spring-boot.jar for examples:
● Logback
● Log4j 2
● Java Util logging
You can add MDC and other ad-hoc content to log lines by overriding only the
LOG_LEVEL_PATTERN (or logging.pattern.level with Logback). For
example, if you use logging.pattern.level=user:%X{user} %5p, then
the default log format contains an MDC entry for "user", if it exists, as shown in the
following example.
JSON
Spring Boot provides integration with three JSON mapping libraries:
● Gson
● Jackson
● JSON-B
Jackson
Auto-configuration for Jackson is provided and Jackson is part of spring-boot-
starter-json. When Jackson is on the classpath an ObjectMapper bean is
automatically configured. Several configuration properties are provided for customizing the
configuration of the ObjectMapper.
Gson
Auto-configuration for Gson is provided. When Gson is on the classpath a Gson bean is
automatically configured. Several spring.gson.* configuration properties are provided
for customizing the configuration. To take more control, one or more
GsonBuilderCustomizer beans can be used.
JSON-B
Auto-configuration for JSON-B is provided. When the JSON-B API and an implementation
are on the classpath a Jsonb bean will be automatically configured. The preferred JSON-B
implementation is Apache Johnzon for which dependency management is provided.
The following code shows a typical @RestController that serves JSON data:
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
Spring MVC is part of the core Spring Framework, and detailed information is available in the
reference documentation. There are also several guides that cover Spring MVC available at
spring.io/guides.
If you want to keep Spring Boot MVC features and you want to add additional MVC
configuration (interceptors, formatters, view controllers, and other features), you can add
your own @Configuration class of type WebMvcConfigurer but without
@EnableWebMvc. If you wish to provide custom instances of
RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or
ExceptionHandlerExceptionResolver, you can declare a
WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own
@Configuration annotated with @EnableWebMvc.
HttpMessageConverters
Spring MVC uses the HttpMessageConverter interface to convert HTTP requests and
responses. Sensible defaults are included out of the box. For example, objects can be
automatically converted to JSON (by using the Jackson library) or XML (by using the
Jackson XML extension, if available, or by using JAXB if the Jackson XML extension is not
available). By default, strings are encoded in UTF-8.
If you need to add or customize converters, you can use Spring Boot’s
HttpMessageConverters class, as shown in the following listing:
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
Any HttpMessageConverter bean that is present in the context is added to the list of
converters. You can also override default converters in the same way.
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;
@JsonComponent
public class Example {
MessageCodesResolver
Spring MVC has a strategy for generating error codes for rendering error messages from
binding errors: MessageCodesResolver. If you set thespring.mvc.message-
codes-resolver.format property PREFIX_ERROR_CODE or
POSTFIX_ERROR_CODE, Spring Boot creates one for you (see the enumeration
inDefaultMessageCodesResolver.Format).
Static Content
By default, Spring Boot serves static content from a directory called /static (or /public
or /resources or /META-INF/resources) in the classpath or from the root of the
ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so
that you can modify that behavior by adding your own WebMvcConfigurerand overriding
the addResourceHandlers method.
In a stand-alone web application, the default servlet from the container is also enabled and
acts as a fallback, serving content from the root of the ServletContext if Spring decides
not to handle it. Most of the time, this does not happen (unless you modify the default MVC
configuration), because Spring can always handle requests through the
DispatcherServlet.
By default, resources are mapped on /**, but you can tune that with the
spring.mvc.static-path-pattern property. For instance, relocating all resources
to/resources/** can be achieved as follows:
spring.mvc.static-path-pattern=/resources/**
You can also customize the static resource locations by using the
spring.resources.static-locations property (replacing the default values with
a list of directory locations). The root Servlet context path, "/", is automatically added as a
location as well.
Welcome Page
Spring Boot supports both static and templated welcome pages. It first looks for an
index.html file in the configured static content locations. If one is not found, it then looks
for an index template. If either is found, it is automatically used as the welcome page of the
application.
Custom Favicon
Spring Boot looks for a favicon.ico in the configured static content locations and the
root of the classpath (in that order). If such a file is present, it is automatically used as the
favicon of the application.
Spring Boot chooses to disable suffix pattern matching by default, which means that
requests like "GET /projects/spring-boot.json" won’t be matched
to@GetMapping("/projects/spring-boot") mappings. This is considered as a
best practice for Spring MVC applications. This feature was mainly useful in the past for
HTTP clients which did not send proper "Accept" request headers; we needed to make sure
to send the correct Content Type to the client. Nowadays, Content Negotiation is much more
reliable.
There are other ways to deal with HTTP clients that don’t consistently send proper "Accept"
request headers. Instead of using suffix matching, we can use a query parameter to ensure
that requests like "GET /projects/spring-boot?format=json" will be mapped
to @GetMapping("/projects/spring-boot"):
spring.mvc.contentnegotiation.favor-parameter=true
Template Engines
As well as REST web services, you can also use Spring MVC to serve dynamic HTML
content. Spring MVC supports a variety of templating technologies, including Thymeleaf,
FreeMarker, and JSPs. Also, many other templating engines include their own Spring MVC
integrations.
Spring Boot includes auto-configuration support for the following templating engines:
● FreeMarker
● Groovy
● Thymeleaf
● Mustache
Error Handling
By default, Spring Boot provides an /error mapping that handles all errors in a sensible
way, and it is registered as a “global” error page in the servlet container. For machine clients,
it produces a JSON response with details of the error, the HTTP status, and the exception
message. For browser clients, there is a “whitelabel” error view that renders the same data
in HTML format (to customize it, add a View that resolves to error). To replace the default
behavior completely, you can implementErrorController and register a bean definition
of that type or add a bean of type ErrorAttributes to use the existing mechanism but
replace the contents.
The BasicErrorController can be used as a base class
You can also define a class annotated with @ControllerAdvice to customize the JSON
document to return for a particular controller and/or exception type, as shown in the following
example:
@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice extends ResponseEntityExceptionHandler
{
@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest
request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(),
ex.getMessage()), status);
}
For example, to map 404 to a static HTML file, your folder structure would be as follows:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
To map all 5xx errors by using a FreeMarker template, your folder structure would be as
follows:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
For more complex mappings, you can also add beans that implement the
ErrorViewResolver interface, as shown in the following example:
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
You can also use regular Spring MVC features such as @ExceptionHandler methods
and @ControllerAdvice. The ErrorController then picks up any unhandled
exceptions.
Spring HATEOAS
If you develop a RESTful API that makes use of hypermedia, Spring Boot provides auto-
configuration for Spring HATEOAS that works well with most applications. The auto-
configuration replaces the need to use @EnableHypermediaSupport and registers a
number of beans to ease building hypermedia-based applications, including
aLinkDiscoverers (for client side support) and an ObjectMapper configured to
correctly marshal responses into the desired representation. The ObjectMapper is
customized by setting the various spring.jackson.* properties or, if one exists, by a
Jackson2ObjectMapperBuilder bean.
CORS Support
Cross-origin resource sharing (CORS) is a W3C specification implemented by most
browsers that lets you specify in a flexible way what kind of cross-domain requests are
authorized, instead of using some less secure and less powerful approaches such as
IFRAME or JSONP.
As of version 4.2, Spring MVC supports CORS. Using controller method CORS configuration
with @CrossOrigin annotations in your Spring Boot application does not require any
specific configuration. Global CORS configuration can be defined by registering a
WebMvcConfigurer bean with a customizedaddCorsMappings(CorsRegistry)
method, as shown in the following example:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
By default, if the context contains only a single Servlet, it is mapped to /. In the case of
multiple servlet beans, the bean name is used as a path prefix. Filters map to/*.
If you need to perform servlet context initialization in a Spring Boot application, you should
register a bean that implements
theorg.springframework.boot.web.servlet.ServletContextInitializ
er interface. The single onStartup method provides access to the ServletContext
and, if necessary, can easily be used as an adapter to an existing
WebApplicationInitializer.
The ServletWebServerApplicationContext
Under the hood, Spring Boot uses a different type of ApplicationContext for
embedded servlet container support. The ServletWebServerApplicationContext
is a special type of WebApplicationContext that bootstraps itself by searching for a
single ServletWebServerFactory bean. Usually a
TomcatServletWebServerFactory, JettyServletWebServerFactory, or
UndertowServletWebServerFactory has been auto-configured.
Spring Boot tries as much as possible to expose common settings, but this is not always
possible. For those cases, dedicated namespaces offer server-specific customizations (see
server.tomcat and server.undertow). For instance, access logs can be configured
with specific features of the embedded servlet container.
Programmatic Customization
If you need to programmatically configure your embedded servlet container, you can register
a Spring bean that implements the WebServerFactoryCustomizerinterface.
WebServerFactoryCustomizer provides access to the
ConfigurableServletWebServerFactory, which includes numerous
customization setter methods. The following example shows programmatically setting the
port:
import
org.springframework.boot.web.server.WebServerFactoryCustomizer;
import
org.springframework.boot.web.servlet.server.ConfigurableServletWe
bServerFactory;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory
server) {
server.setPort(9000);
}
}
TomcatServletWebServerFactory,
JettyServletWebServerFactory and
UndertowServletWebServerFactory are dedicated variants of
ConfigurableServletWebServerFactory that have additional
customization setter methods for Tomcat, Jetty and Undertow respectively.
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new
TomcatServletWebServerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/notfound.html"));
return factory;
}
Setters are provided for many configuration options. Several protected method “hooks” are
also provided should you need to do something more exotic. See the source code
documentation for details.
JSP Limitations
When running a Spring Boot application that uses an embedded servlet container (and is
packaged as an executable archive), there are some limitations in the JSP support.
● With Jetty and Tomcat, it should work if you use war packaging. An executable war
will work when launched with java -jar, and will also be deployable to any
standard container. JSPs are not supported when using an executable jar.
● Undertow does not support JSPs.
● Creating a custom error.jsp page does not override the default view for error
handling. Custom error pages should be used instead.
There is a JSP sample so that you can see how to set things up.
By default, those resources will be also shared with the Reactor Netty and Jetty clients for
optimal performances, given:
Developers can override the resource configuration for Jetty and Reactor Netty by providing
a custom ReactorResourceFactory or JettyResourceFactory bean - this will
be applied to both clients and servers.
You can learn more about the resource configuration on the client side in the WebClient
Runtime section.
Security
If Spring Security is on the classpath, then web applications are secured by default. Spring
Boot relies on Spring Security’s content-negotiation strategy to determine whether to use
httpBasic or formLogin. To add method-level security to a web application, you can
also add @EnableGlobalMethodSecurity with your desired settings. Additional
information can be found in the Spring Security Reference Guide.
The default UserDetailsService has a single user. The user name is user, and the
password is random and is printed at INFO level when the application starts, as shown in the
following example:
MVC Security
The default security configuration is implemented in SecurityAutoConfiguration
and UserDetailsServiceAutoConfiguration.
SecurityAutoConfigurationimports
SpringBootWebSecurityConfiguration for web security and
UserDetailsServiceAutoConfiguration configures authentication, which is also
relevant in non-web applications. To switch off the default web application security
configuration completely, you can add a bean of type
WebSecurityConfigurerAdapter (doing so does not disable the
UserDetailsService configuration or Actuator’s security).
To also switch off the UserDetailsService configuration, you can add a bean of type
UserDetailsService, AuthenticationProvider, or
AuthenticationManager. There are several secure applications in the Spring Boot
samples to get you started with common use cases.
WebFlux Security
Similar to Spring MVC applications, you can secure your WebFlux applications by adding the
spring-boot-starter-security dependency. The default security configuration is
implemented in ReactiveSecurityAutoConfiguration and
UserDetailsServiceAutoConfiguration.
ReactiveSecurityAutoConfigurationimports
WebFluxSecurityConfiguration for web security and
UserDetailsServiceAutoConfiguration configures authentication, which is also
relevant in non-web applications. To switch off the default web application security
configuration completely, you can add a bean of type WebFilterChainProxy (doing so
does not disable the UserDetailsService configuration or Actuator’s security).
To also switch off the UserDetailsService configuration, you can add a bean of type
ReactiveUserDetailsService or ReactiveAuthenticationManager.
For example, you can customize your security configuration by adding something like:
@Bean
public SecurityWebFilterChain
springSecurityFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.matchers(PathRequest.toStaticResources().atCommonLocations
()).permitAll()
.pathMatchers("/foo", "/bar")
.authenticated().and()
.formLogin().and()
.build();
}
OAuth2
OAuth2 is a widely used authorization framework that is supported by Spring.
Client
If you have spring-security-oauth2-client on your classpath, you can take
advantage of some auto-configuration to make it easy to set up an OAuth2/Open ID Connect
clients. This configuration makes use of the properties under
OAuth2ClientProperties. The same properties are applicable to both servlet and
reactive applications.
You can register multiple OAuth2 clients and providers under the
spring.security.oauth2.client prefix, as shown in the following example:
spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-
secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client
for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-
provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri-
template=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-
authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-
grant-type=authorization_code
spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-
secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client
for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-
provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri-
template=http://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-
authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-
grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-
uri=http://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-
uri=http://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-
uri=http://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-
authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-
uri=http://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-
attribute=name
For OpenID Connect providers that support OpenID Connect discovery, the configuration
can be further simplified. The provider needs to be configured with an issuer-uri which
is the URI that the it asserts as its Issuer Identifier. For example, if the issuer-uri
provided is "https://example.com", then an OpenID Provider Configuration
Request will be made to "https://example.com/.well-known/openid-configuration". The
result is expected to be an OpenID Provider Configuration Response. The
following example shows how an OpenID Connect Provider can be configured with the
issuer-uri:
spring.security.oauth2.client.provider.oidc-provider.issuer-
uri=https://dev-123456.oktapreview.com/oauth2/default/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.redirectionEndpoint()
.baseUri("/custom-callback");
}
}
If you do not need to customize these providers, you can set the provider attribute to the
one for which you need to infer defaults. Also, if the key for the client registration matches a
default supported provider, Spring Boot infers that as well.
In other words, the two configurations in the following example use the Google provider:
spring.security.oauth2.client.registration.my-client.client-
id=abcd
spring.security.oauth2.client.registration.my-client.client-
secret=password
spring.security.oauth2.client.registration.my-
client.provider=google
spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-
secret=password
Resource Server
If you have spring-security-oauth2-resource-server on your classpath,
Spring Boot can set up an OAuth2 Resource Server as long as a JWK Set URI or OIDC
Issuer URI is specified, as shown in the following examples:
spring.security.oauth2.resourceserver.jwt.jwk-set-
uri=https://example.com/oauth2/default/v1/keys
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-
123456.oktapreview.com/oauth2/default/
The same properties are applicable for both servlet and reactive applications.
Alternatively, you can define your own JwtDecoder bean for servlet applications or a
ReactiveJwtDecoder for reactive applications.
Authorization Server
Currently, Spring Security does not provide support for implementing an OAuth 2.0
Authorization Server. However, this functionality is available from the Spring Security OAuth
project, which will eventually be superseded by Spring Security completely. Until then, you
can use the spring-security-oauth2-autoconfigure module to easily set up an
OAuth 2.0 authorization server; see its documentation for instructions.
Actuator Security
For security purposes, all actuators other than /health and /info are disabled by
default. The management.endpoints.web.exposure.include property can be
used to enable the actuators.
Additional information about CSRF protection can be found in the Spring Security Reference
Guide.
Configure a DataSource
Java’s javax.sql.DataSource interface provides a standard method of working with
database connections. Traditionally, a 'DataSource' uses a URL along with some credentials
to establish a database connection.
Spring Boot can auto-configure embedded H2, HSQL, and Derby databases. You need not
provide any connection URLs. You need only include a build dependency to the embedded
database that you want to use.
If you are using this feature in your tests, you may notice that the
same database is reused by your whole test suite regardless of the
number of application contexts that you use. If you want to make
sure that each context has a separate embedded database, you
should set spring.datasource.generate-unique-name
to true.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
You need a dependency on spring-jdbc for an embedded
database to be auto-configured. In this example, it is pulled in
transitively throughspring-boot-starter-data-jpa.
If, for whatever reason, you do configure the connection URL for
an embedded database, take care to ensure that the database’s
automatic shutdown is disabled. If you use H2, you should use
DB_CLOSE_ON_EXIT=FALSE to do so. If you use HSQLDB,
you should ensure that shutdown=true is not used.
Disabling the database’s automatic shutdown lets Spring Boot
control when the database is closed, thereby ensuring that it
happens once access to the database is no longer needed.
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
valid Driver class is available, so we check for that before doing anything. In
See DataSourceProperties for more of the supported options. These are the
standard options that work regardless of the actual implementation. It is also possible to fine-
tune implementation-specific settings by using their respective prefix
(spring.datasource.hikari.*, spring.datasource.tomcat.*, and
spring.datasource.dbcp2.*). Refer to the documentation of the connection pool
implementation you are using for more details.
For instance, if you use the Tomcat connection pool, you could customize many additional
settings, as shown in the following example:
Using JdbcTemplate
Spring’s JdbcTemplate and NamedParameterJdbcTemplate classes are auto-
configured, and you can @Autowire them directly into your own beans, as shown in the
following example:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
spring.jdbc.template.max-rows=500
The NamedParameterJdbcTemplate reuses the same
Entity Classes
Traditionally, JPA “Entity” classes are specified in a persistence.xml file. With Spring
Boot, this file is not necessary and “Entity Scanning” is used instead. By default, all
packages below your main configuration class (the one annotated with
@EnableAutoConfiguration or @SpringBootApplication) are searched.
package com.example.myapp.domain;
import java.io.Serializable;
import javax.persistence.*;
@Entity
public class City implements Serializable {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
protected City() {
// no-args constructor required by JPA spec
// this one is protected since it shouldn't be used directly
}
// ... etc
}
For more complex queries, you can annotate your method with Spring Data’s Query
annotation.
The following example shows a typical Spring Data repository interface definition:
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
}
Spring Data JPA repositories support three different modes of bootstrapping: default,
deferred, and lazy. To enable deferred or lazy bootstrapping, set
thespring.data.jpa.repositories.bootstrap-mode to deferred or lazy
respectively. When using deferred or lazy bootstrapping, the auto-configured
EntityManagerFactoryBuilder will use the context’s AsyncTaskExecutor, if
any, as the bootstrap executor. If more than one exists, the one named
applicationTaskExecutor will be used.
spring.jpa.hibernate.ddl-auto=create-drop
Hibernate’s own internal property name for this (if you happen
to remember it better) is hibernate.hbm2ddl.auto. You
can set it, along with other Hibernate native properties, by using
spring.jpa.properties.* (the prefix is stripped before
adding them to the entity manager). The following line shows an
example of setting JPA properties for Hibernate:
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
The line in the preceding example passes a value of true for the
hibernate.globally_quoted_identifiers property to the Hibernate entity
manager.
By default, the DDL execution (or validation) is deferred until the ApplicationContext
has started. There is also a spring.jpa.generate-ddl flag, but it is not used if
Hibernate auto-configuration is active, because the ddl-auto settings are more fine-
grained.
Spring Boot will auto-configure Spring Data’s JDBC repositories when the necessary
dependencies are on the classpath. They can be added to your project with a single
dependency on spring-boot-starter-data-jdbc. If necessary, you can take
control of Spring Data JDBC’s configuration by adding the
@EnableJdbcRepositoriesannotation or a JdbcConfiguration subclass to your
application.
If you are not using Spring Boot’s developer tools but would still
like to make use of H2’s console, you can configure the
spring.h2.console.enabledproperty with a value of
true.
Using jOOQ
Java Object Oriented Querying (jOOQ) is a popular product from Data Geekery which
generates Java code from your database and lets you build type-safe SQL queries through
its fluent API. Both the commercial and open source editions can be used with Spring Boot.
Code Generation
In order to use jOOQ type-safe queries, you need to generate Java classes from your
database schema. You can follow the instructions in the jOOQ user manual. If you use the
jooq-codegen-maven plugin and you also use the spring-boot-starter-
parent “parent POM”, you can safely omit the plugin’s <version> tag. You can also use
Spring Boot-defined version variables (such as h2.version) to declare the plugin’s
database dependency. The following listing shows an example:
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
...
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<configuration>
<jdbc>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/yourdatabase</url>
</jdbc>
<generator>
...
</generator>
</configuration>
</plugin>
Using DSLContext
The fluent API offered by jOOQ is initiated through the org.jooq.DSLContext
interface. Spring Boot auto-configures a DSLContext as a Spring Bean and connects it to
your application DataSource. To use the DSLContext, you can @Autowire it, as
shown in the following example:
@Component
public class JooqExample implements CommandLineRunner {
private final DSLContext create;
@Autowired
public JooqExample(DSLContext dslContext) {
this.create = dslContext;
}
You can then use the DSLContext to construct your queries, as shown in the following
example:
Redis
Redis is a cache, message broker, and richly-featured key-value store. Spring Boot offers
basic auto-configuration for the Lettuce and Jedis client libraries and the abstractions on top
of them provided by Spring Data Redis.
Connecting to Redis
You can inject an auto-configured RedisConnectionFactory,
StringRedisTemplate, or vanilla RedisTemplate instance as you would any other
Spring Bean. By default, the instance tries to connect to a Redis server at
localhost:6379. The following listing shows an example of such a bean:
@Component
public class MyBean {
@Autowired
public MyBean(StringRedisTemplate template) {
this.template = template;
}
// ...
}
You can also register an arbitrary number of beans that implement
LettuceClientConfigurationBuilderCustomizer for more
advanced customizations. If you use Jedis,
JedisClientConfigurationBuilderCustomizer is also
available.
If you add your own @Bean of any of the auto-configured types, it replaces the default
(except in the case of RedisTemplate, when the exclusion is based on the bean name,
redisTemplate, not its type). By default, if commons-pool2 is on the classpath, you
get a pooled connection factory.