The SpringApplication
class provides a convenient way to bootstrap a Spring application
that will be started from a main()
method. In many situations you can just delegate to
the static SpringApplication.run
method:
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
When your application starts you should see something similar to the following:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: v{spring-boot-version} 2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb) 2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy 2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080 2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
By default INFO
logging messages will be shown, including some relevant startup details
such as the user that launched the application.
The banner that is printed on start up can be changed by adding a banner.txt
file
to your classpath, or by setting banner.location
to the location of such a file.
If the file has an unusual encoding you can set banner.encoding
(default is UTF-8).
If the SpringApplication
defaults aren’t to your taste you can instead create a local
instance and customize it. For example, to turn off the banner you would write:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setShowBanner(false);
app.run(args);
}
Note
|
The constructor arguments passed to SpringApplication are configuration sources
for spring beans. In most cases these will be references to @Configuration classes, but
they could also be references to XML configuration or to packages that should be scanned.
|
It is also possible to configure the SpringApplication
using an application.properties
file. See 'Externalized Configuration' for details.
For a complete list of the configuration options, see the
{dc-spring-boot}/SpringApplication.{dc-ext}[SpringApplication
Javadoc].
If you need to build an ApplicationContext
hierarchy (multiple contexts with a
parent/child relationship), or if you just prefer using a `fluent'' builder API, you
can use the `SpringApplicationBuilder
.
The SpringApplicationBuilder
allows you to chain together multiple method calls, and
includes parent
and child
methods that allow you to create a hierarchy.
For example:
new SpringApplicationBuilder()
.showBanner(false)
.sources(Parent.class)
.child(Application.class)
.run(args);
Note
|
There are some restrictions when creating an ApplicationContext hierarchy, e.g.
Web components must be contained within the child context, and the same Environment
will be used for both parent and child contexts. See the
{dc-spring-boot}/builder/SpringApplicationBuilder.{dc-ext}[SpringApplicationBuilder javadoc]
for full details.
|
In addition to the usual Spring Framework events, such as
{spring-javadoc}/context/event/ContextRefreshedEvent.{dc-ext}[ContextRefreshedEvent
],
a SpringApplication
sends some additional application events. Some events are actually
triggered before the ApplicationContext
is created.
You can register event listeners in a number of ways, the most common being
SpringApplication.addListeners(…)
method.
Application events are sent in the following order, as your application runs:
-
An
ApplicationStartedEvent
is sent at the start of a run, but before any processing except the registration of listeners and initializers. -
An
ApplicationEnvironmentPreparedEvent
is sent when theEnvironment
to be used in the context is known, but before the context is created. -
An
ApplicationPreparedEvent
is sent just before the refresh is started, but after bean definitions have been loaded. -
An
ApplicationFailedEvent
is sent if there is an exception on startup.
Tip
|
You often won’t need to use application events, but it can be handy to know that they exist. Internally, Spring Boot uses events to handle a variety of tasks. |
A SpringApplication
will attempt to create the right type of ApplicationContext
on
your behalf. By default, an AnnotationConfigApplicationContext
or
AnnotationConfigEmbeddedWebApplicationContext
will be used, depending on whether you
are developing a web application or not.
The algorithm used to determine a `web environment'' is fairly simplistic (based on the
presence of a few classes). You can use `setWebEnvironment(boolean webEnvironment)
if
you need to override the default.
It is also possible to take complete control of the ApplicationContext
type that will
be used by calling setApplicationContextClass(…)
.
Tip
|
It is often desirable to call setWebEnvironment(false) when using SpringApplication
within a JUnit test.
|
If you want access to the raw command line arguments, or you need to run some specific code
once the SpringApplication
has started you can implement the CommandLineRunner
interface. The run(String… args)
method will be called on all Spring beans
implementing this interface.
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
You can additionally implement the org.springframework.core.Ordered
interface or use the
org.springframework.core.annotation.Order
annotation if several CommandLineRunner
beans are defined that must be called in a specific order.
Each SpringApplication
will register a shutdown hook with the JVM to ensure that the
ApplicationContext
is closed gracefully on exit. All the standard Spring lifecycle
callbacks (such as the DisposableBean
interface, or the @PreDestroy
annotation) can
be used.
In addition, beans may implement the org.springframework.boot.ExitCodeGenerator
interface if they wish to return a specific exit code when the application ends.
Spring Boot allows you to externalize your configuration so 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 using the @Value
annotation, accessed
via Spring’s Environment
abstraction or bound to structured objects.
Spring Boot uses a very particular PropertySource
order that is designed to allow
sensible overriding of values, properties are considered in the the following order:
-
Command line arguments.
-
Java System properties (
System.getProperties()
). -
OS environment variables.
-
JNDI attributes from
java:comp/env
-
A
RandomValuePropertySource
that only has properties inrandom.*
. -
Application properties outside of your packaged jar (
application.properties
including YAML and profile variants). -
Application properties packaged inside your jar (
application.properties
including YAML and profile variants). -
@PropertySource
annotations on your@Configuration
classes. -
Default properties (specified using
SpringApplication.setDefaultProperties
).
To provide a concrete example, suppose you develop a @Component
that uses a
name
property:
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
You can bundle an application.properties
inside your jar that provides a sensible
default name
. When running in production, an application.properties
can be provided
outside of your jar that overrides name
; and for one-off testing, you can launch with
a specific command line switch (e.g. java -jar app.jar --name="Spring"
).
The RandomValuePropertySource
is useful for injecting random values (e.g. into secrets
or test cases). It can produce integers, longs or strings, e.g.
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
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 (exclusive).
By default SpringApplication
will convert any command line option arguments (starting
with `--'', e.g. `--server.port=9000
) to a property
and add it to the Spring
Environment
. As mentioned above, command line properties always take precedence over
other property sources.
If you don’t want command line properties to be added to the Environment
you can disable
them using SpringApplication.setAddCommandLineProperties(false)
.
SpringApplication
will load properties from application.properties
files in the
following locations and add them to the Spring Environment
:
-
A
/config
subdir of the current directory. -
The current directory
-
A classpath
/config
package -
The classpath root
The list is ordered by precedence (locations higher in the list override lower items).
Note
|
You can also use YAML ('.yml') files as an alternative to '.properties'. |
If you don’t like application.properties
as the configuration file name you can switch
to another by specifying a spring.config.name
environment property. You can also refer
to an explicit location using the spring.config.location
environment property
(comma-separated list of directory locations, or file paths).
$ java -jar myproject.jar --spring.config.name=myproject
or
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
If spring.config.location
contains directories (as opposed to files) they should end
in /
(and will be appended with the names generated from spring.config.name
before
being loaded). The default search path classpath:,classpath:/config,file:,file:config/
is always used, irrespective of the value of spring.config.location
. In that way you
can set up default values for your application in application.properties
(or whatever
other basename you choose with spring.config.name
) and override it at runtime with a
different file, keeping the defaults.
Note
|
If you use environment variables rather than system properties, most operating
systems disallow period-separated key names, but you can use underscores instead (e.g.
SPRING_CONFIG_NAME instead of spring.config.name ).
|
Note
|
If you are running in a container then JNDI properties (in java:comp/env ) or
servlet context initialization parameters can be used instead of, or as well as,
environment variables or system properties.
|
In addition to application.properties
files, profile specific properties can also be
defined using the naming convention application-{profile}.properties
.
Profile specific properties are loaded from the same locations as standard
application.properties
, with profile specific files overriding the default ones.
The values in application.properties
are filtered through the existing Environment
when they are used so you can refer back to previously defined values (e.g. from System
properties).
app.name=MyApp
app.description=${app.name} is a Spring Boot application
Tip
|
You can also use this technique to create ``short'' variants of existing Spring Boot properties. See the 'howto.adoc' how-to for details. |
YAML is a superset of JSON, and as such is a very convenient format
for specifying hierarchical configuration data. The SpringApplication
class will
automatically support YAML as an alternative to properties whenever you have the
SnakeYAML library on your classpath.
Note
|
If you use `starter POMs'' SnakeYAML will be automatically provided via
`spring-boot-starter .
|
Spring Boot provides two convenient classes that can be used to load YAML documents. The
YamlPropertiesFactoryBean
will load YAML as Properties
and the YamlMapFactoryBean
will load YAML as a Map
.
For example, the following YAML document:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
Would be transformed into these properties:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML lists are represented as property keys with [index]
dereferencers,
for example this YAML:
my:
servers:
- dev.bar.com
- foo.bar.com
Would be transformed into these properties:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
To bind to properties like that using the Spring DataBinder
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, e.g. this will bind to the properties above
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
The YamlPropertySourceLoader
class can be used to expose YAML as a PropertySource
in the Spring Environment
. This allows you to use the familiar @Value
annotation with
placeholders syntax to access YAML properties.
You can specify multiple profile-specific YAML documents in a single file by
using a spring.profiles
key to indicate when the document applies. For example:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
In the example above, the server.address
property will be 127.0.0.1
if the
development
profile is active. If the development
and production
profiles are not
enabled, then the value for the property will be 192.168.1.100
Using the @Value("${property}")
annotation to inject configuration properties can
sometimes be cumbersome, especially if you are working with multiple properties or
your data is hierarchical in nature. Spring Boot provides an alternative method
of working with properties that allows strongly typed beans to govern and validate
the configuration of your application. For example:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
When the @EnableConfigurationProperties
annotation is applied to your @Configuration
,
any beans annotated with @ConfigurationProperties
will be automatically configured
from the Environment
properties. This style of configuration works particularly well
with the SpringApplication
external YAML configuration:
# application.yml
connection:
username: admin
remoteAddress: 192.168.1.1
# additional configuration as required
To work with @ConfigurationProperties
beans you can just inject them in the same way
as any other bean.
@Service
public class MyService {
@Autowired
private ConnectionSettings connection;
//...
@PostConstruct
public void openConnection() {
Server server = new Server();
this.connection.configure(server);
}
}
It is also possible to shortcut the registration of @ConfigurationProperties
bean
definitions by simply listing the properties classes directly in the
@EnableConfigurationProperties
annotation:
@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
public class MyConfiguration {
}
Spring Boot uses some relaxed rules for binding Environment
properties to
@ConfigurationProperties
beans, so there doesn’t need to be an exact match between
the Environment
property name and the bean property name. Common examples where this
is useful include underscore separated (e.g. context_path
binds to contextPath
), and
capitalized (e.g. PORT
binds to port
) environment properties.
Spring will attempt to coerce the external application properties to the right type when
it binds to the @ConfigurationProperties
beans. If you need custom type conversion you
can provide a ConversionService
bean (with bean id conversionService
) or custom
property editors (via a CustomEditorConfigurer
bean).
Spring Boot will attempt to validate external configuration, by default using JSR-303
(if it is on the classpath). You can simply add JSR-303 javax.validation
constraint
annotations to your @ConfigurationProperties
class:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
You can also add a custom Spring Validator
by creating a bean definition called
configurationPropertiesValidator
.
Tip
|
The spring-boot-actuator module includes an endpoint that exposes all
@ConfigurationProperties beans. Simply point your web browser to /configprops
or use the equivalent JMX endpoint. See the
'Production ready features'.
section for details.
|
Spring Profiles provide a way to segregate parts of your application configuration and
make it only available in certain environments. Any @Component
or @Configuration
can
be marked with @Profile
to limit when it is loaded:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
In the normal Spring way, you can use a spring.profiles.active
Environment
property to specify which profiles are active. You can
specify the property in any of the usual ways, for example you could
include it in your application.properties
:
spring.profiles.active=dev,hsqldb
or specify on the command line using the switch --spring.profiles.active=dev,hsqldb
.
The spring.profiles.active
property follows the same ordering rules as other
properties, the highest PropertySource
will win. This means that you can specify
active profiles in application.properties
then replace them using the command line
switch.
Sometimes it is useful to have profile specific properties that add to the active
profiles rather than replace them. The spring.profiles.include
property can be used
to unconditionally add active profiles. The SpringApplication
entry point also has
a Java API for setting additional profiles (i.e. on top of those activated by the
spring.profiles.active
property): see the setAdditionalProfiles()
method.
For example, when an application with following properties is run using the switch
--spring.profiles.active=prod
the proddb
and prodmq
profiles will also be activated:
---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include: proddb,prodmq
Note
|
Remember that the spring.profiles property can be defined in a YAML document
to determine when this particular document is included in the configuration. See
[howto-change-configuration-depending-on-the-environment] for more details.
|
You can programmatically set active profiles by calling
SpringApplication.setAdditionalProfiles(…)
before your application runs. It is also
possible to activate profiles using Spring’s ConfigurableEnvironment
interface.
Profile specific variants of both application.properties
(or application.yml
) and
files referenced via @ConfigurationProperties
are considered as files are loaded.
See 'Profile specific properties' for details.
Spring Boot uses Commons Logging for all internal logging, but leaves the underlying log implementation open. Default configurations are provided for Java Util Logging, Log4J and Logback. In each case there is console output and file output (rotating, 10 Mb file size).
By default, if you use the ``Starter POMs'', Logback will be used for logging. Appropriate Logback routing is also included to ensure that dependent libraries that use Java Util Logging, Commons Logging, Log4J or SLF4J will all work correctly.
Tip
|
There are a lot of logging frameworks available for Java. Don’t worry if the above list seems confusing. Generally you won’t need to change your logging dependencies and the Spring Boot defaults will work just fine. |
The default log output from Spring Boot looks like this:
2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
The following items are output:
-
Date and Time — Millisecond precision and easily sortable.
-
Log Level —
ERROR
,WARN
,INFO
,DEBUG
orTRACE
. -
Process ID.
-
A
---
separator to distinguish the start of actual log messages. -
Logger name — This is usually the source class name (often abbreviated).
-
The log message.
The default log configuration will echo messages to the console as they are written. By
default ERROR
, WARN
and INFO
level messages are logged. To also log DEBUG
level
messages to the console you can start your application with a --debug
flag.
$ java -jar myapp.jar --debug
If your terminal supports ANSI, color output will be used to aid readability. You can set
spring.output.ansi.enabled
to a
{dc-spring-boot}/ansi/AnsiOutput.Enabled.{dc-ext}[supported value] to override the auto
detection.
By default, log files are written to spring.log
in your temp
directory and rotate at
10 Mb. You can easily customize the output folder by setting the logging.path
property
(for example in your application.properties
). It is also possible to change the filename
using a logging.file
property. Note that if logging.file
is used, then setting logging.path
has no effect.
As with console output, ERROR
, WARN
and INFO
level messages are logged by default.
All the supported logging systems can have the logger levels set in the Spring
Environment
(so for example in application.properties
) using logging.level.*=LEVEL''
where
LEVEL'' is one of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Example
application.properties
:
logging.level.org.springframework.web: DEBUG
logging.level.org.hibernate: ERROR
The various logging systems can be activated by including the appropriate libraries on
the classpath, and further customized by providing a suitable configuration file in the
root of the classpath, or in a location specified by the Spring Environment
property
logging.config
. (Note however that since logging is initialized before the
ApplicationContext
is created, it isn’t possible to control logging from
@PropertySources
in Spring @Configuration
files. System properties and the
conventional Spring Boot external configuration files work just fine.)
Depending on your logging system, the following files will be loaded:
Logging System | Customization |
---|---|
Logback |
|
Log4j |
|
JDK (Java Util Logging) |
|
To help with the customization some other properties are transferred from the Spring
Environment
to System properties:
Spring Environment | System Property | Comments |
---|---|---|
|
|
Used in default log configuration if defined. |
|
|
Used in default log configuration if defined. |
|
|
The current process ID (discovered if possible and when not already defined as an OS environment variable). |
All the logging systems supported can consult System properties when parsing their
configuration files. See the default configurations in spring-boot.jar
for examples.
Warning
|
There are known classloading issues with Java Util Logging that cause problems when running from an ``executable jar''. We recommend that you avoid it if at all possible. |
Spring Boot is well suited for web application development. You can easily create a
self-contained HTTP server using embedded Tomcat or Jetty. Most web applications will
use the spring-boot-starter-web
module to get up and running quickly.
If you haven’t yet developed a Spring Boot web application you can follow the "Hello World!" example in the 'Getting started' section.
The Spring Web MVC framework (often referred to as simply Spring MVC'') is a rich
model view controller'' web framework. Spring MVC lets you create special @Controller
or @RestController
beans to handle incoming HTTP requests. Methods in your controller
are mapped to HTTP using @RequestMapping
annotations.
Here is a typical example @RestController
to serve 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 {spring-reference}#mvc[reference documentation]. There are also several guides available at http://spring.io/guides that cover Spring MVC.
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans. -
Support for serving static resources, including support for WebJars (see below).
-
Automatic registration of
Converter
,GenericConverter
,Formatter
beans. -
Support for
HttpMessageConverters
(see below). -
Automatic registration of
MessageCodeResolver
(see below) -
Static
index.html
support. -
Custom
Favicon
support.
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
. If you want to keep Spring Boot MVC features, and
you just want to add additional {spring-reference}#mvc[MVC configuration] (interceptors,
formatters, view controllers etc.) you can add your own @Bean
of type
WebMvcConfigurerAdapter
, but without @EnableWebMvc
.
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 (using the Jackson library) or XML (using JAXB).
If you need to add or customize converters you can use Spring Boot’s
HttpMessageConverters
class:
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);
}
}
Spring MVC has a strategy for generating error codes for rendering error messages
from binding errors: MessageCodesResolver
. Spring Boot will create one for you if
you set the spring.mvc.message-codes-resolver.format
property PREFIX_ERROR_CODE
or
POSTFIX_ERROR_CODE
(see the enumeration in DefaultMessageCodesResolver.Format
).
By default Spring Boot will serve static content from a folder 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 you
can modify that behavior by adding your own WebMvcConfigurerAdapter
and 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 will not happen (unless you modify
the default MVC configuration) because Spring will always be able to handle requests
through the DispatcherServlet
.
In addition to the `standard'' static resource locations above, a special case is made for
Webjars content. Any resources with a path in `/webjars/**
will
be served from jar files if they are packaged in the Webjars format.
Tip
|
Do not use the src/main/webapp folder if your application will be packaged as a
jar. Although this folder is a common standard, it will only work with war packaging
and it will be silently ignored by most build tools if you generate a jar.
|
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 Velocity, FreeMarker and JSPs. Many other templating engines also ship their own Spring MVC integrations.
Spring Boot includes auto-configuration support for the following templating engines:
When you’re using one of these templating engines with the default configuration, your
templates will be picked up automatically from src/main/resources/templates
.
Tip
|
JSPs should be avoided if possible, there are several known limitations when using them with embedded servlet containers. |
Spring Boot provides an /error
mapping by default 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 will produce 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 just add a View
that
resolves to `error''). To replace the default behaviour completely you can implement
`ErrorController
and register a bean definition of that type, or simply add a bean
of type ErrorAttributes
to use the existing mechanism but replace the contents.
If you want more specific error pages for some conditions, the embedded servlet containers support a uniform Java DSL for customizing the error handling. For example:
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer(){
return new MyCustomizer();
}
// ...
private static class MyCustomizer implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}
}
You can also use regular Spring MVC features like
{spring-reference}/#mvc-exceptionhandlers[@ExceptionHandler
methods] and
{spring-reference}/#mvc-ann-controller-advice[@ControllerAdvice
]. The ErrorController
will then pick up any unhandled exceptions.
N.B. if you register an ErrorPage
with a path that will end up being handled by a
Filter
(e.g. as is common with some non-Spring web frameworks, like Jersey and Wicket),
then the Filter
has to be explicitly registered as an ERROR
dispatcher, e.g.
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
(the default FilterRegistrationBean
does not include the ERROR
dispatcher type).
When deployed to a servlet container, a Spring Boot uses its error page filter to
forward a request with an error status to the appropriate error page. The request can
only be forwarded to the correct error page if the response has not already been
committed. By default, WebSphere Application Server 8.0 and later commits the response
upon successful completion of a servlet’s service method. You should disable this
behaviour by setting com.ibm.ws.webcontainer.invokeFlushAfterService
to false
If you prefer the JAX-RS programming model for REST endpoints you can use one of the
available implementations instead of Spring MVC. Jersey 1.x and Apache Celtix work
quite well out of the box if you just register their Servlet
or Filter
as a
@Bean
in your application context. Jersey 2.x has some native Spring support so
we also provide autoconfiguration support for it in Spring Boot together with a
starter.
To get started with Jersey 2.x just include the spring-boot-starter-jersey
as a dependency
and then you need one @Bean
of type ResourceConfig
in which you register all the
endpoints:
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
}
}
All the registered endpoints should be @Components
with HTTP resource annotations (@GET
etc.), e.g.
@Component
@Path("/hello")
public class Endpoint {
@GET
public String message() {
return "Hello";
}
}
Since the Endpoint
is a Spring @Component
its lifecycle
is managed by Spring and you can @Autowired
dependencies and inject
external configuration with @Value
. The Jersey servlet will be
registered and mapped to "/\*" by default. You can change the mapping
by adding @ApplicationPath
to your ResourceConfig
.
There is a {github-code}/spring-boot-samples/spring-boot-sample-jersey[Jersey sample] so
you can see how to set things up. There is also a {github-code}/spring-boot-samples/spring-boot-sample-jersey1[Jersey 1.x sample].
Note that in the Jersey 1.x sample that the spring-boot maven plugin has been configured to
unpack some Jersey jars so they can be scanned by the JAX-RS implementation (the sample
asks for them to be scanned in its Filter
registration.
Spring Boot includes support for embedded Tomcat and Jetty servers. Most developers will
simply use the appropriate `Starter POM'' to obtain a fully configured instance. By
default both Tomcat and Jetty will listen for HTTP requests on port `8080
.
When using an embedded servlet container you can register Servlets and Filters directly as
Spring beans. This can be particularly convenient if you want to refer to a value from
your application.properties
during configuration.
By default, if the context contains only a single Servlet it will be mapped to /
. In
the case of multiple Servlets beans the bean name will be used as a path prefix. Filters
will map to /*
.
If convention-based mapping is not flexible enough you can use the
ServletRegistrationBean
and FilterRegistrationBean
classes for complete control. You
can also register items directly if your bean implements the ServletContextInitializer
interface.
Under the hood Spring Boot uses a new type of ApplicationContext
for embedded
servlet container support. The EmbeddedWebApplicationContext
is a special
type of WebApplicationContext
that bootstraps itself by searching for a single
EmbeddedServletContainerFactory
bean. Usually a TomcatEmbeddedServletContainerFactory
or JettyEmbeddedServletContainerFactory
will have been auto-configured.
Note
|
You usually won’t need to be aware of these implementation classes. Most
applications will be auto-configured and the appropriate ApplicationContext and
EmbeddedServletContainerFactory will be created on your behalf.
|
Common servlet container settings can be configured using Spring Environment
properties. Usually you would define the properties in your application.properties
file.
Common server settings include:
-
server.port
— The listen port for incoming HTTP requests. -
server.address
— The interface address to bind to. -
server.sessionTimeout
— A session timeout.
See the {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[ServerProperties
]
class for a complete list.
If you need to configure your embdedded servlet container programmatically you can register
a Spring bean that implements the EmbeddedServletContainerCustomizer
interface.
EmbeddedServletContainerCustomizer
provides access to the
ConfigurableEmbeddedServletContainer
which includes numerous customization setter
methods.
import org.springframework.boot.context.embedded.*;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(9000);
}
}
If the above customization techniques are too limited, you can register the
TomcatEmbeddedServletContainerFactory
or JettyEmbeddedServletContainerFactory
bean
yourself.
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.404, "/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.
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 Tomcat it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to a standard container (not limited to, but including Tomcat). An executable jar will not work because of a hard coded file pattern in Tomcat.
-
Jetty does not currently work as an embedded container with JSPs.
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so you can see how to set things up.
If Spring Security is on the classpath then web applications will be secure by default
with `basic'' authentication on all HTTP endpoints. 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}#jc-method[Spring
Security Reference].
The default AuthenticationManager
has a single user (``user'' username and random
password, printed at INFO level when the application starts up)
Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
You can change the password by providing a security.user.password
. This and other
useful properties are externalized via
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[SecurityProperties
]
(properties prefix "security").
The default security configuration is implemented in SecurityAutoConfiguration
and in
the classes imported from there (SpringBootWebSecurityConfiguration
for web security
and AuthenticationManagerConfiguration
for authentication configuration which is also
relevant in non-web applications). To switch off the Boot default configuration
completely in a web application you can add a bean with @EnableWebSecurity
. To customize
it you normally use external properties and beans of type WebConfigurerAdapter
(e.g. to
add form-based login). There are several secure applications in the
{github-code}/spring-boot-samples/[Spring Boot samples] to get you started with common
use cases.
The basic features you get out of the box in a web application are:
-
An
AuthenticationManager
bean with in-memory store and a single user (seeSecurityProperties.User
for the properties of the user). -
Ignored (unsecure) paths for common static resource locations (
/css/
,/js/
,/images/
and/favicon.ico
). -
HTTP Basic security for all other endpoints.
-
Security events published to Spring’s
ApplicationEventPublisher
(successful and unsuccessful authentication and access denied). -
Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are on by default.
All of the above can be switched on and off or modified using external properties
(security.*
). To override the access rules without changing any other autoconfigured
features add a @Bean
of type WebConfigurerAdapter
with
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
.
If the Actuator is also in use, you will find:
-
The management endpoints are secure even if the application endpoints are unsecure.
-
Security events are transformed into
AuditEvents
and published to theAuditService
. -
The default user will have the
ADMIN
role as well as theUSER
role.
The Actuator security features can be modified using external properties
(management.security.*
). To override the application access rules
add a @Bean
of type WebConfigurerAdapter
and use
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
if you don’t want to override
the actuator access rules, or @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
if you do want to override the actuator access rules.
The Spring Framework provides extensive support for working with SQL databases. From
direct JDBC access using JdbcTemplate
to complete `object relational mapping''
technologies such as Hibernate. Spring Data provides an additional level of functionality,
creating `Repository
implementations directly from interfaces and using conventions to
generate queries from your method names.
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.
It’s often convenient to develop applications using an in-memory embedded database. Obviously, in-memory databases do not provide persistent storage; you will need to populate your database when your application starts and be prepared to throw away data when your application ends.
Tip
|
The ``How-to'' section includes a 'section on how to initialize a database' |
Spring Boot can auto-configure embedded H2, HSQL and Derby databases. You don’t need to provide any connection URLs, simply include a build dependency to the embedded database that you want to use.
For example, typical POM dependencies would be:
<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>
Note
|
You need a dependency on spring-jdbc for an embedded database to be
auto-configured. In this example it’s pulled in transitively via
spring-boot-starter-data-jpa .
|
Production database connections can also be auto-configured using a pooling
DataSource
. Here’s the algorithm for choosing a specific implementation.
-
We prefer the Tomcat pooling
DataSource
for its performance and concurrency, so if that is available we always choose it. -
If HikariCP is available we will use it
-
If Commons DBCP is available we will use it, but we don’t recommend it in production.
-
Lastly, if Commons DBCP2 is available we will use it
If you use the spring-boot-starter-jdbc
or spring-boot-starter-data-jpa
`starter POMs'' you will automatically get a dependency to `tomcat-jdbc
.
Note
|
Additional connection pools can always be configured manually. If you define your
own DataSource bean, auto-configuration will not occur.
|
DataSource configuration is controlled by external configuration properties in
spring.datasource.*
. For example, you might declare the following section
in application.properties
:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
See {sc-spring-boot-autoconfigure}/jdbc/DataSourceProperties.{sc-ext}[DataSourceProperties
]
for more of the supported options.
Tip
|
You often won’t need to specify the driver-class-name since Spring boot can deduce
it for most databases from the url .
|
Note
|
For a pooling DataSource to be created we need to be able to verify that a valid
Driver class is available, so we check for that before doing anything. I.e. if you set
spring.datasource.driverClassName=com.mysql.jdbc.Driver then that class has to be
loadable.
|
If you are deploying your Spring Boot application to an Application Server you might want to configure and manage your DataSource using you Application Servers built in features and access it using JNDI.
The spring.datasource.jndi-name
property can be used as an alternative to the
spring.datasource.url
, spring.datasource.username
and spring.datasource.password
properties to access the DataSource
from a specific JNDI location. For example, the
following section in application.properties
shows how you can access a JBoss AS defined
DataSource
:
spring.datasource.jndi-name=java:jboss/datasources/customers
Spring’s JdbcTemplate
and NamedParameterJdbcTemplate
classes are auto-configured and
you can @Autowire
them directly into your own beans:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
}
The Java Persistence API is a standard technology that allows you to `map'' objects to
relational databases. The `spring-boot-starter-data-jpa
POM provides a quick way to get
started. It provides the following key dependencies:
-
Hibernate — One of the most popular JPA implementations.
-
Spring Data JPA — Makes it easy to easily implement JPA-based repositories.
-
Spring ORMs — Core ORM support from the Spring Framework.
Tip
|
We won’t go into too many details of JPA or Spring Data here. You can follow the ``Accessing Data with JPA'' guide from http://spring.io and read the Spring Data JPA and Hibernate reference documentation. |
Traditionally, JPA Entity'' classes are specified in a
Entity Scanning'' is used. By
default all packages below your main configuration class (the one annotated with
persistence.xml
file. With
Spring Boot this file is not necessary and instead @EnableAutoConfiguration
) will be searched.
Any classes annotated with @Entity
, @Embeddable
or @MappedSuperclass
will be
considered. A typical entity class would look something like this:
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;
// ... additional members, often include @OneToMany mappings
protected City() {
// no-args constructor required by JPA spec
// this one is protected since it shouldn't be used directly
}
public City(String name, String state) {
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
// ... etc
}
Tip
|
You can customize entity scanning locations using the @EntityScan annotation.
See the 'howto.adoc'
how-to.
|
Spring Data JPA repositories are interfaces that you can define to access data. JPA
queries are created automatically from your method names. For example, a CityRepository
interface might declare a findAllByState(String state)
method to find all cities
in a given state.
For more complex queries you can annotate your method using Spring Data’s
{spring-data-javadoc}/repository/Query.html[Query
] annotation.
Spring Data repositories usually extend from the
{spring-data-commons-javadoc}/repository/Repository.html[Repository
] or
{spring-data-commons-javadoc}/repository/CrudRepository.html[CrudRepository
] interfaces. If you are using
auto-configuration, repositories will be searched from the package containing your
main configuration class (the one annotated with @EnableAutoConfiguration
) down.
Here is a typical Spring Data repository:
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}
Tip
|
We have barely scratched the surface of Spring Data JPA. For complete details check their reference documentation. |
By default JPA database will be automatically created only if you use an embedded
database (H2, HSQL or Derby). You can explicitly configure JPA settings using
spring.jpa.*
properties. For example, to create and drop tables you can add the
following to your application.properties
.
spring.jpa.hibernate.ddl-auto=create-drop
Note
|
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, using spring.jpa.properties.* (the prefix is stripped before adding them
to the entity manager). Example:
|
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
passes hibernate.globally_quoted_identifiers
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 autoconfig is active because the ddl-auto
settings are more fine grained.
Spring Data provides additional projects that help you access a variety of NoSQL technologies including MongoDB, Neo4J, Elasticsearch, Solr, Redis, Gemfire, Couchbase and Cassandra. Spring Boot provides auto-configuration for Redis, MongoDB, Elasticsearch, Solr and Gemfire; you can make use of the other projects, but you will need to configure them yourself. Refer to the appropriate reference documentation at projects.spring.io/spring-data.
Redis is a cache, message broker and richly-featured key-value store.
Spring Boot offers basic auto-configuration for the Jedis
client library and abstractions on top of it provided by
Spring Data Redis. There is a
spring-boot-starter-redis
``Starter POM'' for collecting the dependencies in a
convenient way.
You can inject an auto-configured RedisConnectionFactory
, StringRedisTemplate
or
vanilla RedisTemplate
instance as you would any other Spring Bean. By default the
instance will attempt to connect to a Redis server using localhost:6379
:
@Component
public class MyBean {
private StringRedisTemplate template;
@Autowired
public MyBean(StringRedisTemplate template) {
this.template = template;
}
// ...
}
If you add a @Bean
of your own of any of the auto-configured types it will replace the
default (except in the case of RedisTemplate
the exclusion is based on the bean name
`redisTemplate'' not its type). If `commons-pool2
is on the classpath you will get a
pooled connection factory by default.
MongoDB is an open-source NoSQL document database that uses a
JSON-like schema instead of traditional table-based relational data. Spring Boot offers
several conveniences for working with MongoDB, including the The
spring-boot-starter-data-mongodb
``Starter POM''.
You can inject an auto-configured com.mongodb.Mongo
instance as you would any other
Spring Bean. By default the instance will attempt to connect to a MongoDB server using
the URL mongodb://localhost/test
:
import com.mongodb.Mongo;
@Component
public class MyBean {
private final Mongo mongo;
@Autowired
public MyBean(Mongo mongo) {
this.mongo = mongo;
}
// ...
}
You can set spring.data.mongodb.uri
property to change the url
, or alternatively
specify a host
/port
. For example, you might declare the following in your
application.properties
:
spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017
Tip
|
If spring.data.mongodb.port is not specified the default of 27017 is used. You
could simply delete this line from the sample above.
|
You can also declare your own Mongo
@Bean
if you want to take complete control of
establishing the MongoDB connection.
Spring Data Mongo provides a {spring-data-mongo-javadoc}/core/MongoTemplate.html[MongoTemplate
]
class that is very similar in its design to Spring’s JdbcTemplate
. As with
JdbcTemplate
Spring Boot auto-configures a bean for you to simply inject:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final MongoTemplate mongoTemplate;
@Autowired
public MyBean(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
// ...
}
See the MongoOperations
Javadoc for complete details.
Spring Data includes repository support for MongoDB. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.
In fact, both Spring Data JPA and Spring Data MongoDB share the same common
infrastructure; so you could take the JPA example from earlier and, assuming that
City
is now a Mongo data class rather than a JPA @Entity
, it will work in the
same way.
package com.example.myapp.domain;
import org.springframework.data.domain.*;
import org.springframework.data.repository.*;
public interface CityRepository extends Repository<City, Long> {
Page<City> findAll(Pageable pageable);
City findByNameAndCountryAllIgnoringCase(String name, String country);
}
Tip
|
For complete details of Spring Data MongoDB, including its rich object mapping technologies, refer to their reference documentation. |
Spring Data Gemfire provides
convenient Spring-friendly tools for accessing the Pivotal Gemfire
data management platform. There is a spring-boot-starter-data-gemfire
``Starter POM''
for collecting the dependencies in a convenient way. There is currently no auto=config
support for Gemfire, but you can enable Spring Data Repositories with a
single annotation.
Apache Solr is a search engine. Spring Boot offers basic
auto-configuration for the solr client library and abstractions on top of it provided by
Spring Data Solr. There is
a spring-boot-starter-data-solr
``Starter POM'' for collecting the dependencies in a
convenient way.
You can inject an auto-configured SolrServer
instance as you would any other Spring
Bean. By default the instance will attempt to connect to a server using
http://localhost:8983/solr
:
@Component
public class MyBean {
private SolrServer solr;
@Autowired
public MyBean(SolrServer solr) {
this.solr = solr;
}
// ...
}
If you add a @Bean
of your own of type SolrServer
it will replace the default.
Spring Data includes repository support for Apache Solr. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.
In fact, both Spring Data JPA and Spring Data Solr share the same common infrastructure;
so you could take the JPA example from earlier and, assuming that City
is now a
@SolrDocument
class rather than a JPA @Entity
, it will work in the same way.
Tip
|
For complete details of Spring Data Solr, refer to their reference documentation. |
Elastic Search is an open source, distributed,
real-time search and analytics engine. Spring Boot offers basic auto-configuration for
the Elasticsearch and abstractions on top of it provided by
Spring Data Elasticsearch.
There is a spring-boot-starter-data-elasticsearch
``Starter POM'' for collecting the
dependencies in a convenient way.
You can inject an auto-configured ElasticsearchTemplate
or Elasticsearch Client
instance as you would any other Spring Bean. By default the instance will attempt to
connect to a local in-memory server (a NodeClient
in Elasticsearch terms), but you can
switch to a remote server (i.e. a TransportClient
) by setting
spring.data.elasticsearch.clusterNodes
to a comma-separated ``host:port'' list.
@Component
public class MyBean {
private ElasticsearchTemplate template;
@Autowired
public MyBean(ElasticsearchTemplate template) {
this.template = template;
}
// ...
}
If you add a @Bean
of your own of type ElasticsearchTemplate
it will replace the
default.
Spring Data includes repository support for Elasticsearch. As with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.
In fact, both Spring Data JPA and Spring Data Elasticsearch share the same common
infrastructure; so you could take the JPA example from earlier and, assuming that
City
is now an Elasticsearch @Document
class rather than a JPA @Entity
, it will
work in the same way.
Tip
|
For complete details of Spring Data Elasticsearch, refer to their reference documentation. |
The Spring Framework provides extensive support for integrating with messaging systems:
from simplified use of the JMS API using JmsTemplate
to a complete infrastructure to
receive messages asynchronously. Spring AMQP provides a similar feature set for the
`Advanced Message Queuing Protocol'' and Boot also provides auto-configuration options
for `RabbitTemplate
and RabbitMQ. There is also support for STOMP messaging natively
in Spring Websocket and Spring Boot has support for that through starters and a small
amount of auto configuration.
The javax.jms.ConnectionFactory
interface provides a standard method of creating a
javax.jms.Connection
for interacting with a JMS broker. Although Spring needs a
ConnectionFactory
to work with JMS, you generally won’t need to use it directly yourself
and you can instead rely on higher level messaging abstractions (see the
{spring-reference}/#jms[relevant section] of the Spring Framework reference
documentation for details). Spring Boot also auto configures the necessary infrastructure
to send and receive messages.
Spring Boot can auto-configure a ConnectionFactory
when it detects that HornetQ is
available on the classpath. If the broker is present, an embedded broker is started and
configured automatically (unless the mode property has been explicitly set). The supported
modes are: embedded
(to make explicit that an embedded broker is required and should
lead to an error if the broker is not available in the classpath), and native
to
connect to a broker using the the netty
transport protocol. When the latter is
configured, Spring Boot configures a ConnectionFactory
connecting to a broker running
on the local machine with the default settings.
Note
|
if you are using spring-boot-starter-hornetq the necessary dependencies to
connect to an existing HornetQ instance are provided, as well as the Spring infrastructure
to integrate with JMS. Adding org.hornetq:hornetq-jms-server to your application allows
you to use the embedded mode.
|
HornetQ configuration is controlled by external configuration properties in
spring.hornetq.*
. For example, you might declare the following section in
application.properties
:
spring.hornetq.mode=native
spring.hornetq.host=192.168.1.210
spring.hornetq.port=9876
When embedding the broker, you can chose if you want to enable persistence, and the list
of destinations that should be made available. These can be specified as a comma separated
list to create them with the default options; or you can define bean(s) of type
org.hornetq.jms.server.config.JMSQueueConfiguration
or
org.hornetq.jms.server.config.TopicConfiguration
, for advanced queue and topic
configurations respectively.
See {sc-spring-boot-autoconfigure}/jms/hornetq/HornetQProperties.{sc-ext}[HornetQProperties
]
for more of the supported options.
No JNDI lookup is involved at all and destinations are resolved against their names, either using the ``name'' attribute in the HornetQ configuration or the names provided through configuration.
Spring Boot can also configure a ConnectionFactory
when it detects that ActiveMQ is
available on the classpath. If the broker is present, an embedded broker is started and
configured automatically (as long as no broker URL is specified through configuration).
ActiveMQ configuration is controlled by external configuration properties in
spring.activemq.*
. For example, you might declare the following section in
application.properties
:
spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret
See {sc-spring-boot-autoconfigure}/jms/activemq/ActiveMQProperties.{sc-ext}[ActiveMQProperties
]
for more of the supported options.
By default, ActiveMQ creates a destination if it does not exist yet, so destinations are resolved against their provided names.
If you are running your application in an Application Server Spring Boot will attempt to
locate a JMS ConnectionFactory
using JNDI. By default the locations java:/JmsXA
and
java:/XAConnectionFactory
will be checked. You can use the
spring.jms.jndi-name
property if you need to specify an alternative location:
spring.jms.jndi-name=java:/MyConnectionFactory
Spring’s JmsTemplate
is auto-configured and you can autowire it directly into your
own beans:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JmsTemplate jmsTemplate;
@Autowired
public MyBean(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
// ...
}
Note
|
{spring-javadoc}/jms/core/JmsMessagingTemplate.{dc-ext}[JmsMessagingTemplate ]
(new in Spring 4.1) can be injected in a similar manner.
|
When the JMS infrastructure is present, any bean can be annotated with @JmsListener
to
create a listener endpoint. If no JmsListenerContainerFactory
has been defined, a default
one is configured automatically.
The following component creates a listener endpoint on the someQueue
destination:
@Component
public class MyBean {
@JmsListener(destination = "someQueue")
public void processMessage(String content) { ... }
}
Check {spring-javadoc}/jms/annotation/EnableJms.{dc-ext}[the javadoc of @EnableJms
]
for more details.
Spring Boot supports distributed JTA transactions across multiple XA resources using either an Atomkos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server.
When a JTA environment is detected, Spring’s JtaTransactionManager
will be used to manage
transactions. Auto-configured JMS, DataSource and JPA beans will be upgraded to support
XA transactions. You can use standard Spring idioms such as @Transactional
to
participate in a distributed transaction.
Atomikos is a popular open source transaction manager which can be embedded into your
Spring Boot application. You can use the spring-boot-starter-jta-atomikos
Starter POM to
pull in the appropriate Atomikos libraries. Spring Boot will auto-configure Atomikos and
ensure that appropriate depends-on
settings are applied to your Spring Beans for correct
startup and shutdown ordering.
By default Atomikos transaction logs will be written to a transaction-logs
folder in
your application home directory (the directory in which your application jar file
resides). You can customize this directory by setting a spring.jta.log-dir
property in
your application.properties
file. Properties starting spring.jta.
can also be used to
customize the Atomikos UserTransactionServiceIml
. See the
{dc-spring-boot}/jta/atomikos/AtomikosProperties.{dc-ext}[AtomikosProperties
javadoc]
for complete details.
Bitronix is another popular open source JTA transaction manager implementation. You can
use the spring-boot-starter-jta-bitronix
starter POM to add the appropriate Birtronix
dependencies to your project. As with Atomikos, Spring Boot will automatically configure
Bitronix and post-process your beans to ensure that startup and shutdown ordering is
correct.
By default Bitronix transaction log files (part1.btm
and part2.btm
) will be written to
a transaction-logs
folder in your application home directory. You can customize this
directory by using the spring.jta.log-dir
property. Properties starting spring.jta.
are also bound to the bitronix.tm.Configuration
bean, allowing for complete
customization. See the Bitronix
documentation for details.
If you are packaging your Spring Boot application as a war
or ear
file and deploying
it to a Java EE application server, you can use your application servers built-in
transaction manager. Spring Boot will attempt to auto-configure a transaction manager by
looking at common JNDI locations (java:comp/UserTransaction
,
java:comp/TransactionManager
etc). If you are using a transaction service provided by
your application server, you will generally also want to ensure that all resources are
managed by the server and exposed over JNDI. Spring Boot will attempt to auto-configure
JMS by looking for a ConnectionFactory
at the JNDI path java:/JmsXA
or
java:/XAConnectionFactory
and you can use the
spring.datasource.jndi-name
property
to configure your DataSource
.
When using JTA, the primary JMS ConnectionFactory
bean will be XA aware and participate
in distributed transactions. In some situations you might want to process certain JMS
messages using a non-XA ConnectionFactory
. For example, your JMS processing logic might
take longer than the XA timeout.
If you want to use a non-XA ConnectionFactory
you can inject the
nonXaJmsConnectionFactory
bean rather than the @Primary
jmsConnectionFactory
bean.
For consistency the jmsConnectionFactory
bean is also provided using the bean alias
xaJmsConnectionFactory
.
For example:
// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;
// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;
// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;
The {sc-spring-boot}/jta/XAConnectionFactoryWrapper.{sc-ext}[XAConnectionFactoryWrapper
]
and {sc-spring-boot}/jta/XADataSourceWrapper.{sc-ext}[XADataSourceWrapper
] interfaces
can be used to support alternative embedded transaction managers. The interfaces are
responsible for wrapping XAConnectionFactory
and XADataSource
beans and exposing them
as regular ConnectionFactory
and DataSource
beans which will transparently enroll in
the distributed transaction. DataSource and JMS auto-configuration will use JTA variants
as long as you have a JtaTransactionManager
bean and appropriate XA wrapper beans
registered within your ApplicationContext
The {sc-spring-boot}/jta/BitronixXAConnectionFactoryWrapper.{sc-ext}[BitronixXAConnectionFactoryWrapper] and {sc-spring-boot}/jta/BitronixXADataSourceWrapper.{sc-ext}[BitronixXADataSourceWrapper] provide good examples of how to write XA wrappers.
Spring Integration provides abstractions over messaging and also other transports such as
HTTP, TCP etc. If Spring Integration is available on your classpath it will be initialized
through the @EnableIntegration
annotation. Message processing statistics will be
published over JMX if `spring-integration-jmx'' is also on the classpath.
See the {sc-spring-boot-autoconfigure}/integration/IntegrationAutoConfiguration.{sc-ext}[`IntegrationAutoConfiguration
]
class for more details.
Java Management Extensions (JMX) provide a standard mechanism to monitor and manage
applications. By default Spring Boot will create an MBeanServer
with bean id
`mbeanServer'' and expose any of your beans that are annotated with Spring JMX
annotations (
@ManagedResource`, @ManagedAttribute
, @ManagedOperation
).
See the {sc-spring-boot-autoconfigure}/jmx/JmxAutoConfiguration.{sc-ext}[JmxAutoConfiguration
]
class for more details.
Spring Boot provides a number of useful tools for testing your application. The
spring-boot-starter-test
POM provides Spring Test, JUnit, Hamcrest and Mockito
dependencies. There are also useful test utilities in the core spring-boot
module
under the org.springframework.boot.test
package.
If you use the
spring-boot-starter-test
`Starter POM'' (in the `test
scope
), you will find
the following provided libraries:
-
Spring Test — integration test support for Spring applications.
-
Junit — The de-facto standard for unit testing Java applications.
-
Hamcrest — A library of matcher objects (also known as constraints or predicates) allowing
assertThat
style JUnit assertions. -
Mockito — A Java mocking framework.
These are common libraries that we generally find useful when writing tests. You are free to add additional test dependencies of your own if these don’t suit your needs.
One of the major advantages of dependency injection is that it should make your code
easier to unit test. You can simply instantiate objects using the new
operator without
even involving Spring. You can also use mock objects instead of real dependencies.
Often you need to move beyond unit testing'' and start
integration testing'' (with
a Spring ApplicationContext
actually involved in the process). It’s useful to be able
to perform integration testing without requiring deployment of your application or
needing to connect to other infrastructure.
The Spring Framework includes a dedicated test module for just such integration testing.
You can declare a dependency directly to org.springframework:spring-test
or use the
spring-boot-starter-test
``Starter POM'' to pull it in transitively.
If you have not used the spring-test
module before you should start by reading the
{spring-reference}/#testing[relevant section] of the Spring Framework reference
documentation.
A Spring Boot application is just a Spring ApplicationContext
so nothing very special
has to be done to test it beyond what you would normally do with a vanilla Spring context.
One thing to watch out for though is that the external properties, logging and other
features of Spring Boot are only installed in the context by default if you use
SpringApplication
to create it.
Spring Boot provides a @SpringApplicationConfiguration
annotation as an alternative
to the standard spring-test
@ContextConfiguration
annotation. If you use
@SpringApplicationConfiguration
to configure the ApplicationContext
used in your
tests, it will be created via SpringApplication
and you will get the additional Spring
Boot features.
For example:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class CityRepositoryIntegrationTests {
@Autowired
CityRepository repository;
// ...
}
Tip
|
The context loader guesses whether you want to test a web application or not (e.g.
with MockMVC ) by looking for the @WebAppConfiguration annotation. (MockMVC and
@WebAppConfiguration are part of spring-test ).
|
If you want a web application to start up and listen on its normal port, so you can test
it with HTTP (e.g. using RestTemplate
), annotate your test class (or one of its
superclasses) with @IntegrationTest
. This can be very useful because it means you can
test the full stack of your application, but also inject its components into the test
class and use them to assert the internal state of the application after an HTTP
interaction. For Example:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
@WebAppConfiguration
@IntegrationTest
public class CityRepositoryIntegrationTests {
@Autowired
CityRepository repository;
RestTemplate restTemplate = new TestRestTemplate();
// ... interact with the running server
}
Note
|
Spring’s test framework will cache application contexts between tests. Therefore, as long as your tests share the same configuration, the time consuming process of starting and stopping the server will only happen once, regardless of the number of tests that actually run. |
To change the port you can add environment properties to @IntegrationTest
as colon- or
equals-separated name-value pairs, e.g. @IntegrationTest("server.port:9000")
.
Additionally you can set the server.port
and management.port
properties to 0
in order to run your integration tests using random ports. For example:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@IntegrationTest({"server.port=0", "management.port=0"})
public class SomeIntegrationTests {
// ...
}
See [howto-discover-the-http-port-at-runtime] for a description of how you can discover the actual port that was allocated for the duration of the tests.
If you wish to use Spock to test a Spring Boot application you should add a dependency
on Spock’s spock-spring
module to your application’s build. spock-spring
integrates
Spring’s test framework into Spock.
Please note that you cannot use the @SpringApplicationConfiguration
annotation that was
described above as Spock
does not find the
@ContextConfiguration
meta-annotation. To work around this limitation, you should use
the @ContextConfiguration
annotation directly and configure it to use the Spring
Boot specific context loader:
@ContextConfiguration(loader = SpringApplicationContextLoader.class)
class ExampleSpec extends Specification {
// ...
}
A few test utility classes are packaged as part of spring-boot
that are generally
useful when testing your application.
ConfigFileApplicationContextInitializer
is an ApplicationContextInitializer
that
can apply to your tests to load Spring Boot application.properties
files. You can use
this when you don’t need the full features provided by @SpringApplicationConfiguration
.
@ContextConfiguration(classes = Config.class,
initializers = ConfigFileApplicationContextInitializer.class)
EnvironmentTestUtils
allows you to quickly add properties to a
ConfigurableEnvironment
or ConfigurableApplicationContext
. Simply call it with
key=value
strings:
EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");
OutputCapture
is a JUnit Rule
that you can use to capture System.out
and
System.err
output. Simply declare the capture as a @Rule
then use toString()
for assertions:
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.OutputCapture;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class MyTest {
@Rule
public OutputCapture capture = new OutputCapture();
@Test
public void testName() throws Exception {
System.out.println("Hello World!");
assertThat(capture.toString(), containsString("World"));
}
}
TestRestTemplate
is a convenience subclass of Spring’s RestTemplate
that is
useful in integration tests. You can get a vanilla template or one that sends Basic HTTP
authentication (with a username and password). In either case the template will behave
in a test-friendly way: not following redirects (so you can assert the response
location), ignoring cookies (so the template is stateless), and not throwing exceptions
on server-side errors. It is recommended, but not mandatory, to use Apache HTTP Client
(version 4.3.2 or better), and if you have that on your classpath the TestRestTemplate
will respond by configuring the client appropriately.
public class MyTest {
RestTemplate template = new TestRestTemplate();
@Test
public void testRequest() throws Exception {
HttpHeaders headers = template.getForEntity("http://myhost.com", String.class).getHeaders();
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
}
}
If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.
Under the hood, auto-configuration is implemented with standard @Configuration
classes.
Additional @Conditional
annotations are used to constrain when the auto-configuration
should apply. Usually auto-configuration classes use @ConditionalOnClass
and
@ConditionalOnMissingBean
annotations. This ensures that auto-configuration only
applies when relevant classes are found and when you have not declared your own
@Configuration
.
You can browse the source code of spring-boot-autoconfigure
to see the @Configuration
classes that we provide (see the META-INF/spring.factories
file).
Spring Boot checks for the presence of a META-INF/spring.factories
file within your
published jar. The file should list your configuration classes under the
EnableAutoConfiguration
key.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\ com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
You can use the
{sc-spring-boot-autoconfigure}/AutoConfigureAfter.{sc-ext}[@AutoConfigureAfter
] or
{sc-spring-boot-autoconfigure}/AutoConfigureBefore.{sc-ext}[@AutoConfigureBefore
]
annotations if your configuration needs to be applied in a specific order. For example,
if you provide web specific configuration, your class may need to be applied after
WebMvcAutoConfiguration
.
You almost always want to include one or more @Condition
annotations on your
auto-configuration class. The @ConditionalOnMissingBean
is one common example that is
used to allow developers to ``override'' auto-configuration if they are not happy with
your defaults.
Spring Boot includes a number of @Conditional
annotations that you can reuse in your own
code by annotating @Configuration
classes or individual @Bean
methods.
The @ConditionalOnClass
and @ConditionalOnMissingClass
annotations allows configuration
to be skipped based on the presence or absence of specific classes. Due to the fact that
annotation meta-data is parsed using ASM you can actually use the
value
attribute to refer to the real class, even though that class might not actually
appear on the running application classpath. You can also use the name
attribute if you
prefer to specify the class name using a String
value.
The @ConditionalOnBean
and @ConditionalOnMissingBean
annotations allow configurations
to be skipped based on the presence or absence of specific beans. You can use the value
attribute to specify beans by type, or name
to specify beans by name. The search
attribute allows you to limit the ApplicationContext
hierarchy that should be considered
when searching for beans.
Note
|
@Conditional annotations are processed when @Configuration classes are
parsed. Auto-configure @Configuration is always parsed last (after any user defined
beans), however, if you are using these annotations on regular @Configuration classes,
care must be taken not to refer to bean definitions that have not yet been created.
|
The @ConditionalOnResource
annotation allows configuration to be included only when a
specific resource is present. Resources can be specified using the usual Spring
conventions, for example, file:/home/user/test.dat
.
The @ConditionalOnWebApplication
and @ConditionalOnNotWebApplication
annotations
allow configuration to be skipped depending on whether the application is a
'web application'. A web application is any application that is using a Spring
WebApplicationContext
, defines a session
scope or has a StandardServletEnvironment
.
If you want to learn more about any of the classes discussed in this section you can check out the {dc-root}[Spring Boot API documentation] or you can browse the {github-code}[source code directly]. If you have specific questions, take a look at the how-to section.
If you are comfortable with Spring Boot’s core features, you can carry on and read about production-ready features.