You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1456 lines
59 KiB
1456 lines
59 KiB
[[howto]] |
|
= ``How-to'' guides |
|
|
|
[partintro] |
|
-- |
|
This section provides answers to some common '``how do I do that...''' type of questions |
|
that often arise when using Spring Boot. This is by no means an exhaustive list, but it |
|
does cover quite a lot. |
|
|
|
If you are having a specific problem that we don't cover here, you might want to check out |
|
http://stackoverflow.com/tags/spring-boot[stackoverflow.com] to see if someone has |
|
already provided an answer; this is also a great place to ask new questions (please use |
|
the `spring-boot` tag). |
|
|
|
We're also more than happy to extend this section; If you want to add a ``how-to'' you |
|
can send us a {github-code}[pull request]. |
|
-- |
|
|
|
|
|
|
|
[[howto-spring-boot-application]] |
|
== Spring Boot application |
|
|
|
|
|
|
|
[[howto-troubleshoot-auto-configuration]] |
|
=== Troubleshoot auto-configuration |
|
The Spring Boot auto-configuration tries its best to ``do the right thing'', but |
|
sometimes things fail and it can be hard to tell why. |
|
|
|
There is a really useful `AutoConfigurationReport` available in any Spring Boot |
|
`ApplicationContext`. You will see it if you enable `DEBUG` logging output. If you use |
|
the `spring-boot-actuator` there is also an `autoconfig` endpoint that renders the report |
|
in JSON. Use that to debug the application and see what features have been added (and |
|
which not) by Spring Boot at runtime. |
|
|
|
Many more questions can be answered by looking at the source code and the javadoc. Some |
|
rules of thumb: |
|
|
|
* Look for classes called `*AutoConfiguration` and read their sources, in particular the |
|
`@Conditional*` annotations to find out what features they enable and when. Add |
|
`--debug` to the command line or a System property `-Ddebug` to get a log on the |
|
console of all the autoconfiguration decisions that were made in your app. In a running |
|
Actuator app look at the `autoconfig` endpoint (`/autoconfig' or the JMX equivalent) for |
|
the same information. |
|
* Look for classes that are `@ConfigurationProperties` (e.g. |
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`]) |
|
and read from there the available external configuration options. The |
|
`@ConfigurationProperties` has a `name` attribute which acts as a prefix to external |
|
properties, thus `ServerProperties` has `prefix="server"` and its configuration properties |
|
are `server.port`, `server.address` etc. In a running Actuator app look at the |
|
`configprops` endpoint. |
|
* Look for use of `RelaxedEnvironment` to pull configuration values explicitly out of the |
|
`Environment`. It often is used with a prefix. |
|
* Look for `@Value` annotations that bind directly to the `Environment`. This is less |
|
flexible than the `RelaxedEnvironment` approach, but does allow some relaxed binding, |
|
specifically for OS environment variables (so `CAPITALS_AND_UNDERSCORES` are synonyms |
|
for `period.separated`). |
|
* Look for `@ConditionalOnExpression` annotations that switch features on and off in |
|
response to SpEL expressions, normally evaluated with place-holders resolved from the |
|
`Environment`. |
|
|
|
|
|
|
|
[[howto-customize-the-environment-or-application-context]] |
|
=== Customize the Environment or ApplicationContext before it starts |
|
A `SpringApplication` has `ApplicationListeners` and `ApplicationContextInitializers` that |
|
are used to apply customizations to the context or environment. Spring Boot loads a number |
|
of such customizations for use internally from `META-INF/spring.factories`. There is more |
|
than one way to register additional ones: |
|
|
|
* Programmatically per application by calling the `addListeners` and `addInitializers` |
|
methods on `SpringApplication` before you run it. |
|
* Declaratively per application by setting `context.initializer.classes` or |
|
`context.listener.classes`. |
|
* Declaratively for all applications by adding a `META-INF/spring.factories` and packaging |
|
a jar file that the applications all use as a library. |
|
|
|
The `SpringApplication` sends some special `ApplicationEvents` to the listeners (even |
|
some before the context is created), and then registers the listeners for events published |
|
by the `ApplicationContext` as well. See |
|
'<<spring-boot-features.adoc#boot-features-application-events-and-listeners>>' in the |
|
``Spring Boot features'' section for a complete list. |
|
|
|
|
|
|
|
[[howto-build-an-application-context-hierarchy]] |
|
=== Build an ApplicationContext hierarchy (adding a parent or root context) |
|
You can use the `ApplicationBuilder` class to create parent/child `ApplicationContext` |
|
hierarchies. See '<<spring-boot-features.adoc#boot-features-fluent-builder-api>>' |
|
in the ``Spring Boot features'' section for more information. |
|
|
|
|
|
|
|
[[howto-create-a-non-web-application]] |
|
=== Create a non-web application |
|
Not all Spring applications have to be web applications (or web services). If you want to |
|
execute some code in a `main` method, but also bootstrap a Spring application to set up |
|
the infrastructure to use, then it's easy with the `SpringApplication` features of Spring |
|
Boot. A `SpringApplication` changes its `ApplicationContext` class depending on whether it |
|
thinks it needs a web application or not. The first thing you can do to help it is to just |
|
leave the servlet API dependencies off the classpath. If you can't do that (e.g. you are |
|
running 2 applications from the same code base) then you can explicitly call |
|
`SpringApplication.setWebEnvironment(false)`, or set the `applicationContextClass` |
|
property (through the Java API or with external properties). |
|
Application code that you want to run as your business logic can be implemented as a |
|
`CommandLineRunner` and dropped into the context as a `@Bean` definition. |
|
|
|
|
|
|
|
[[howto-properties-and-configuration]] |
|
== Properties & configuration |
|
|
|
|
|
|
|
[[howto-externalize-configuration]] |
|
=== Externalize the configuration of SpringApplication |
|
A `SpringApplication` has bean properties (mainly setters) so you can use its Java API as |
|
you create the application to modify its behavior. Or you can externalize the |
|
configuration using properties in `spring.main.*`. E.g. in `application.properties` you |
|
might have. |
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
spring.main.web_environment=false |
|
spring.main.show_banner=false |
|
---- |
|
|
|
and then the Spring Boot banner will not be printed on startup, and the application will |
|
not be a web application. |
|
|
|
NOTE: The example above also demonstrates how flexible binding allows the use of |
|
underscores (`_`) as well as dashes (`-`) in property names. |
|
|
|
[[howto-change-the-location-of-external-properties]] |
|
=== Change the location of external properties of an application |
|
By default properties from different sources are added to the Spring `Environment` in a |
|
defined order (see '<<spring-boot-features.adoc#boot-features-external-config>>' in |
|
the ``Spring Boot features'' section for the exact order). |
|
|
|
A nice way to augment and modify this is to add `@PropertySource` annotations to your |
|
application sources. Classes passed to the `SpringApplication` static convenience |
|
methods, and those added using `setSources()` are inspected to see if they have |
|
`@PropertySources`, and if they do, those properties are added to the `Environment` early |
|
enough to be used in all phases of the `ApplicationContext` lifecycle. Properties added |
|
in this way have precedence over any added using the default locations, but have lower |
|
priority than system properties, environment variables or the command line. |
|
|
|
You can also provide System properties (or environment variables) to change the behavior: |
|
|
|
* `spring.config.name` (`SPRING_CONFIG_NAME`), defaults to `application` as the root of |
|
the file name. |
|
* `spring.config.location` (`SPRING_CONFIG_LOCATION`) is the file to load (e.g. a classpath |
|
resource or a URL). A separate `Environment` property source is set up for this document |
|
and it can be overridden by system properties, environment variables or the |
|
command line. |
|
|
|
No matter what you set in the environment, Spring Boot will always load |
|
`application.properties` as described above. If YAML is used then files with the ``.yml'' |
|
extension are also added to the list by default. |
|
|
|
See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`] |
|
for more detail. |
|
|
|
|
|
|
|
[[howto-use-short-command-line-arguments]] |
|
=== Use ``short'' command line arguments |
|
Some people like to use (for example) `--port=9000` instead of `--server.port=9000` to |
|
set configuration properties on the command line. You can easily enable this by using |
|
placeholders in `application.properties`, e.g. |
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
server.port=${port:8080} |
|
---- |
|
|
|
TIP: If you have enabled maven filtering for the `application.properties` you may want |
|
to avoid using `${*}` for the tokens to filter as it conflicts with those placeholders. |
|
You can either use `@*@` (i.e. `@maven.token@` instead of `${maven.token}`) or you can |
|
configure the `maven-resources-plugin` to use |
|
http://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other delimiters]. |
|
|
|
NOTE: In this specific case the port binding will work in a PaaS environment like Heroku |
|
and Cloud Foundry, since in those two platforms the `PORT` environment variable is set |
|
automatically and Spring can bind to capitalized synonyms for `Environment` properties. |
|
|
|
|
|
|
|
[[howto-use-yaml-for-external-properties]] |
|
=== Use YAML for external properties |
|
YAML is a superset of JSON and as such is a very convenient syntax for storing external |
|
properties in a hierarchical format. E.g. |
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
spring: |
|
application: |
|
name: cruncher |
|
datasource: |
|
driverClassName: com.mysql.jdbc.Driver |
|
url: jdbc:mysql://localhost/test |
|
server: |
|
port: 9000 |
|
---- |
|
|
|
Create a file called `application.yml` and stick it in the root of your classpath, and |
|
also add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already |
|
included if you use the `spring-boot-starter`). A YAML file is parsed to a Java |
|
`Map<String,Object>` (like a JSON object), and Spring Boot flattens the map so that it |
|
is 1-level deep and has period-separated keys, a lot like people are used to with |
|
`Properties` files in Java. |
|
|
|
The example YAML above corresponds to an `application.properties` file |
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
spring.application.name=cruncher |
|
spring.datasource.driverClassName=com.mysql.jdbc.Driver |
|
spring.datasource.url=jdbc:mysql://localhost/test |
|
server.port=9000 |
|
---- |
|
|
|
See '<<spring-boot-features.adoc#boot-features-external-config-yaml>>' in |
|
the ``Spring Boot features'' section for more information |
|
about YAML. |
|
|
|
[[howto-set-active-spring-profiles]] |
|
=== Set the active Spring profiles |
|
The Spring `Environment` has an API for this, but normally you would set a System profile |
|
(`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`). E.g. |
|
launch your application with a `-D` argument (remember to put it before the main class |
|
or jar archive): |
|
|
|
[indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar |
|
---- |
|
|
|
In Spring Boot you can also set the active profile in `application.properties`, e.g. |
|
|
|
[source,properties,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
spring.profiles.active=production |
|
---- |
|
|
|
A value set this way is replaced by the System property or environment variable setting, |
|
but not by the `SpringApplicationBuilder.profiles()` method. Thus the latter Java API can |
|
be used to augment the profiles without changing the defaults. |
|
|
|
See '<<spring-boot-features.adoc#boot-features-profiles>>' in |
|
the ``Spring Boot features'' section for more information. |
|
|
|
|
|
|
|
[[howto-change-configuration-depending-on-the-environment]] |
|
=== Change configuration depending on the environment |
|
A YAML file is actually a sequence of documents separated by `---` lines, and each |
|
document is parsed separately to a flattened map. |
|
|
|
If a YAML document contains a `spring.profiles` key, then the profiles value |
|
(comma-separated list of profiles) is fed into the Spring |
|
`Environment.acceptsProfiles()` and if any of those profiles is active that document is |
|
included in the final merge (otherwise not). |
|
|
|
Example: |
|
|
|
[source,yaml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
server: |
|
port: 9000 |
|
--- |
|
|
|
spring: |
|
profiles: development |
|
server: |
|
port: 9001 |
|
|
|
--- |
|
|
|
spring: |
|
profiles: production |
|
server: |
|
port: 0 |
|
---- |
|
|
|
In this example the default port is 9000, but if the Spring profile ``development'' is |
|
active then the port is 9001, and if ``production'' is active then it is 0. |
|
|
|
The YAML documents are merged in the order they are encountered (so later values override |
|
earlier ones). |
|
|
|
To do the same thing with properties files you can use `application-${profile}.properties` |
|
to specify profile-specific values. |
|
|
|
|
|
|
|
[[howto-discover-build-in-options-for-external-properties]] |
|
=== Discover built-in options for external properties |
|
Spring Boot binds external properties from `application.properties` (or `.yml`) (and |
|
other places) into an application at runtime. There is not (and technically cannot be) |
|
an exhaustive list of all supported properties in a single location because contributions |
|
can come from additional jar files on your classpath. |
|
|
|
A running application with the Actuator features has a `configprops` endpoint that shows |
|
all the bound and bindable properties available through `@ConfigurationProperties`. |
|
|
|
The appendix includes an <<appendix-application-properties#common-application-properties, |
|
`application.properties`>> example with a list of the most common properties supported by |
|
Spring Boot. The definitive list comes from searching the source code for |
|
`@ConfigurationProperties` and `@Value` annotations, as well as the occasional use of |
|
`RelaxedEnvironment`. |
|
|
|
|
|
|
|
[[howto-embedded-servlet-containers]] |
|
== Embedded servlet containers |
|
|
|
|
|
|
|
[[howto-add-a-servlet-filter-or-servletcontextlistener]] |
|
=== Add a Servlet, Filter or ServletContextListener to an application |
|
`Servlet`, `Filter`, `ServletContextListener` and the other listeners supported by the |
|
Servlet spec can be added to your application as `@Bean` definitions. Be very careful that |
|
they don't cause eager initialization of too many other beans because they have to be |
|
installed in the container very early in the application lifecycle (e.g. it's not a good |
|
idea to have them depend on your `DataSource` or JPA configuration). You can work around |
|
restrictions like that by initializing them lazily when first used instead of on |
|
initialization. |
|
|
|
In the case of `Filters` and `Servlets` you can also add mappings and init parameters by |
|
adding a `FilterRegistrationBean` or `ServletRegistrationBean` instead of or as well as |
|
the underlying component. |
|
|
|
|
|
|
|
[[howto-change-the-http-port]] |
|
=== Change the HTTP port |
|
In a standalone application the main HTTP port defaults to `8080`, but can be set with |
|
`server.port` (e.g. in `application.properties` or as a System property). Thanks to |
|
relaxed binding of `Environment` values you can also use `SERVER_PORT` (e.g. as an OS |
|
environment variable). |
|
|
|
To switch off the HTTP endpoints completely, but still create a `WebApplicationContext`, |
|
use `server.port=-1` (this is sometimes useful for testing). |
|
|
|
For more details look at '<<spring-boot-features.adoc#boot-features-customizing-embedded-containers>>' |
|
in the ``Spring Boot features'' section, or the |
|
{sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source |
|
code. |
|
|
|
|
|
[[howto-user-a-random-unassigned-http-port]] |
|
=== Use a random unassigned HTTP port |
|
To scan for a free port (using OS natives to prevent clashes) use `server.port=0`. |
|
|
|
|
|
|
|
[[howto-discover-the-http-port-at-runtime]] |
|
=== Discover the HTTP port at runtime |
|
You can access the port the server is running on from log output or from the |
|
`EmbeddedWebApplicationContext` via its `EmbeddedServletContainer`. The best way to get |
|
that and be sure that it has initialized is to add a `@Bean` of type |
|
`ApplicationListener<EmbeddedServletContainerInitializedEvent>` and pull the container |
|
out of the event when it is published. |
|
|
|
A really useful thing to do in is to use `@IntegrationTest` to set `server.port=0` |
|
and then inject the actual (``local'') port as a `@Value`. For example: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@RunWith(SpringJUnit4ClassRunner.class) |
|
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class) |
|
@WebAppConfiguration |
|
@IntegrationTest("server.port:0") |
|
public class CityRepositoryIntegrationTests { |
|
|
|
@Autowired |
|
EmbeddedWebApplicationContext server; |
|
|
|
@Value("${local.server.port}") |
|
int port; |
|
|
|
// ... |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[howto-configure-tomcat]] |
|
=== Configure Tomcat |
|
Generally you can follow the advice from |
|
'<<howto-discover-build-in-options-for-external-properties>>' about |
|
`@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at |
|
`EmbeddedServletContainerCustomizer` and various Tomcat specific `*Customizers` that you |
|
can add in one of those. The Tomcat APIs are quite rich so once you have access to the |
|
`TomcatEmbeddedServletContainerFactory` you can modify it in a number of ways. Or the |
|
nuclear option is to add your own `TomcatEmbeddedServletContainerFactory`. |
|
|
|
|
|
|
|
[[howto-terminate-ssl-in-tomcat]] |
|
=== Terminate SSL in Tomcat |
|
Use an `EmbeddedServletContainerCustomizer` and in that add a `TomcatConnectorCustomizer` |
|
that sets up the connector to be secure: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@Bean |
|
public EmbeddedServletContainerCustomizer containerCustomizer(){ |
|
return new MyCustomizer(); |
|
} |
|
|
|
// ... |
|
|
|
private static class MyCustomizer implements EmbeddedServletContainerCustomizer { |
|
|
|
@Override |
|
public void customize(ConfigurableEmbeddedServletContainer factory) { |
|
if(factory instanceof TomcatEmbeddedServletContainerFactory) { |
|
customizeTomcat((TomcatEmbeddedServletContainerFactory) factory)); |
|
} |
|
} |
|
|
|
public void customizeTomcat(TomcatEmbeddedServletContainerFactory factory) { |
|
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { |
|
@Override |
|
public void customize(Connector connector) { |
|
connector.setPort(serverPort); |
|
connector.setSecure(true); |
|
connector.setScheme("https"); |
|
connector.setAttribute("keyAlias", "tomcat"); |
|
connector.setAttribute("keystorePass", "password"); |
|
try { |
|
connector.setAttribute("keystoreFile", |
|
ResourceUtils.getFile("src/ssl/tomcat.keystore").getAbsolutePath()); |
|
} catch (FileNotFoundException e) { |
|
throw new IllegalStateException("Cannot load keystore", e); |
|
} |
|
connector.setAttribute("clientAuth", "false"); |
|
connector.setAttribute("sslProtocol", "TLS"); |
|
connector.setAttribute("SSLEnabled", true); |
|
} |
|
}); |
|
} |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[howto-enable-multiple-connectors-in-tomcat]] |
|
=== Enable Multiple Connectors Tomcat |
|
Add a `org.apache.catalina.connector.Connector` to the |
|
`TomcatEmbeddedServletContainerFactory` which can allow multiple connectors eg a HTTP and |
|
HTTPS connector: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@Bean |
|
public EmbeddedServletContainerFactory servletContainer() { |
|
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); |
|
tomcat.addAdditionalTomcatConnectors(createSslConnector()); |
|
return tomcat; |
|
} |
|
|
|
private Connector createSslConnector() { |
|
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); |
|
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); |
|
try { |
|
File keystore = new ClassPathResource("keystore").getFile(); |
|
File truststore = new ClassPathResource("keystore").getFile(); |
|
connector.setScheme("https"); |
|
connector.setSecure(true); |
|
connector.setPort(8443); |
|
protocol.setSSLEnabled(true); |
|
protocol.setKeystoreFile(keystore.getAbsolutePath()); |
|
protocol.setKeystorePass("changeit"); |
|
protocol.setTruststoreFile(truststore.getAbsolutePath()); |
|
protocol.setTruststorePass("changeit"); |
|
protocol.setKeyAlias("apitester"); |
|
return connector; |
|
} |
|
catch (IOException ex) { |
|
throw new IllegalStateException("can't access keystore: [" + "keystore" |
|
+ "] or truststore: [" + "keystore" + "]", ex); |
|
} |
|
} |
|
---- |
|
|
|
|
|
|
|
[[howto-use-tomcat-behind-a-proxy-server]] |
|
=== Use Tomcat behind a front-end proxy server |
|
Spring Boot will automatically configure Tomcat's `RemoteIpValve` if it detects some |
|
environment settings. This allows you to transparently use the standard `x-forwarded-for` |
|
and `x-forwarded-proto` headers that most front-end proxy servers add. |
|
|
|
You can switch on the valve by adding some entries to application.properties, e.g. |
|
|
|
[indent=0] |
|
---- |
|
server.tomcat.remote_ip_header=x-forwarded-for |
|
server.tomcat.protocol_header=x-forwarded-proto |
|
---- |
|
|
|
Alternatively, you can add the `RemoteIpValve` yourself by adding a |
|
`TomcatEmbeddedServletContainerFactory` bean. |
|
|
|
|
|
|
|
[[howto-use-jetty-instead-of-tomcat]] |
|
=== Use Jetty instead of Tomcat |
|
The Spring Boot starters (`spring-boot-starter-web` in particular) use Tomcat as an |
|
embedded container by default. You need to exclude those dependencies and include the |
|
Jetty one instead. Spring Boot provides Tomcat and Jetty dependencies bundled together |
|
as separate starters to help make this process as easy as possible. |
|
|
|
Example in Maven: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-web</artifactId> |
|
<exclusions> |
|
<exclusion> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-tomcat</artifactId> |
|
</exclusion> |
|
</exclusions> |
|
</dependency> |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-jetty</artifactId> |
|
</dependency> |
|
---- |
|
|
|
Example in Gradle: |
|
|
|
[source,groovy,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
configurations { |
|
compile.exclude module: "spring-boot-starter-tomcat" |
|
} |
|
|
|
dependencies { |
|
compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RC3") |
|
compile("org.springframework.boot:spring-boot-starter-jetty:1.0.0.RC3") |
|
// ... |
|
} |
|
---- |
|
|
|
|
|
|
|
[[howto-configure-jetty]] |
|
=== Configure Jetty |
|
Generally you can follow the advice from |
|
'<<howto-discover-build-in-options-for-external-properties>>' about |
|
`@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at |
|
`EmbeddedServletContainerCustomizer`. The Jetty APIs are quite rich so once you have |
|
access to the `JettyEmbeddedServletContainerFactory` you can modify it in a number |
|
of ways. Or the nuclear option is to add your own `JettyEmbeddedServletContainerFactory`. |
|
|
|
|
|
|
|
[[howto-use-tomcat-8]] |
|
=== Use Tomcat 8 |
|
Tomcat 8 works with Spring Boot, but the default is to use Tomcat 7 (so we can support |
|
Java 1.6 out of the box). You should only need to change the classpath to use |
|
Tomcat 8 for it to work. For example, using the starter poms in Maven: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<properties> |
|
<tomcat.version>8.0.8</tomcat.version> |
|
</properties> |
|
<dependencies> |
|
... |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-web</artifactId> |
|
</dependency> |
|
... |
|
</dependencies> |
|
---- |
|
|
|
change the classpath to use Tomcat 8 for it to work. |
|
|
|
|
|
|
|
[[howto-use-jetty-9]] |
|
=== Use Jetty 9 |
|
Jetty 9 works with Spring Boot, but the default is to use Jetty 8 (so we can support |
|
Java 1.6 out of the box). You should only need to change the classpath to use Jetty 9 |
|
for it to work. |
|
|
|
If you are using the starter poms and parent you can just add the Jetty starter and |
|
change the version properties, e.g. for a simple webapp or service: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<properties> |
|
<java.version>1.7</java.version> |
|
<jetty.version>9.1.0.v20131115</jetty.version> |
|
<servlet-api.version>3.1.0</servlet-api.version> |
|
</properties> |
|
<dependencies> |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-web</artifactId> |
|
<exclusions> |
|
<exclusion> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-tomcat</artifactId> |
|
</exclusion> |
|
</exclusions> |
|
</dependency> |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-jetty</artifactId> |
|
</dependency> |
|
</dependencies> |
|
---- |
|
|
|
|
|
|
|
[[howto-spring-mvc]] |
|
== Spring MVC |
|
|
|
|
|
|
|
[[howto-write-a-json-rest-service]] |
|
=== Write a JSON REST service |
|
Any Spring `@RestController` in a Spring Boot application should render JSON response by |
|
default as long as Jackson2 is on the classpath. For example: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@RestController |
|
public class MyController { |
|
|
|
@RequestMapping("/thing") |
|
public MyThing thing() { |
|
return new MyThing(); |
|
} |
|
|
|
} |
|
---- |
|
|
|
As long as `MyThing` can be serialized by Jackson2 (e.g. a normal POJO or Groovy object) |
|
then `http://localhost:8080/thing` will serve a JSON representation of it by default. |
|
Sometimes in a browser you might see XML responses (but by default only if `MyThing` was |
|
a JAXB object) because browsers tend to send accept headers that prefer XML. |
|
|
|
|
|
|
|
[[howto-write-an-xml-rest-service]] |
|
=== Write an XML REST service |
|
Since JAXB is in the JDK the same example as we used for JSON would work, as long as the |
|
`MyThing` was annotated as `@XmlRootElement`: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@XmlRootElement |
|
public class MyThing { |
|
private String name; |
|
// .. getters and setters |
|
} |
|
---- |
|
|
|
To get the server to render XML instead of JSON you might have to send an |
|
`Accept: text/xml` header (or use a browser). |
|
|
|
|
|
|
|
[[howto-customize-the-jackson-objectmapper]] |
|
=== Customize the Jackson ObjectMapper |
|
Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content |
|
conversion in an HTTP exchange. If Jackson is on the classpath you already get a default |
|
converter with a vanilla `ObjectMapper`. Spring Boot has some features to make it easier |
|
to customize this behavior. |
|
|
|
The smallest change that might work is to just add beans of type |
|
`com.fasterxml.jackson.databind.Module` to your context. They will be registered with the |
|
default `ObjectMapper` and then injected into the default message converter. To replace |
|
the default `ObjectMapper` completely, define a `@Bean` of that type and mark it as |
|
`@Primary`. |
|
|
|
In addition, if your context contains any beans of type `ObjectMapper` then all of the |
|
`Module` beans will be registered with all of the mappers. So there is a global mechanism |
|
for contributing custom modules when you add new features to your application. |
|
|
|
Finally, if you provide any `@Beans` of type `MappingJackson2HttpMessageConverter` then |
|
they will replace the default value in the MVC configuration. Also, a convenience bean is |
|
provided of type `HttpMessageConverters` (always available if you use the default MVC |
|
configuration) which has some useful methods to access the default and user-enhanced |
|
message converters. |
|
|
|
See also the '<<howto-customize-the-responsebody-rendering>>' section and the |
|
{sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] |
|
source code for more details. |
|
|
|
|
|
|
|
[[howto-customize-the-responsebody-rendering]] |
|
=== Customize the @ResponseBody rendering |
|
Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from |
|
`@RestController`). You can contribute additional converters by simply adding beans of |
|
that type in a Spring Boot context. If a bean you add is of a type that would have been |
|
included by default anyway (like `MappingJackson2HttpMessageConverter` for JSON |
|
conversions) then it will replace the default value. A convenience bean is provided of |
|
type `HttpMessageConverters` (always available if you use the default MVC configuration) |
|
which has some useful methods to access the default and user-enhanced message converters |
|
(useful, for example if you want to manually inject them into a custom `RestTemplate`). |
|
|
|
As in normal MVC usage, any `WebMvcConfigurerAdapter` beans that you provide can also |
|
contribute converters by overriding the `configureMessageConverters` method, but unlike |
|
with normal MVC, you can supply only additional converters that you need (because Spring |
|
Boot uses the same mechanism to contribute its defaults). Finally, if you opt-out of the |
|
Spring Boot default MVC configuration by providing your own `@EnableWebMvc` configuration, |
|
then you can take control completely and do everything manually using |
|
`getMessageConverters` from `WebMvcConfigurationSupport`. |
|
|
|
See the {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] |
|
source code for more details. |
|
|
|
|
|
|
|
[[howto-switch-off-the-spring-mvc-dispatcherservlet]] |
|
=== Switch off the Spring MVC DispatcherServlet |
|
Spring Boot wants to serve all content from the root of your application `/` down. If you |
|
would rather map your own servlet to that URL you can do it, but of course you may lose |
|
some of the other Boot MVC features. To add your own servlet and map it to the root |
|
resource just declare a `@Bean` of type `Servlet` and give it the special bean name |
|
`dispatcherServlet` (You can also create a bean of a different type with that name if |
|
you want to switch it off and not replace it). |
|
|
|
|
|
|
|
[[howto-switch-off-default-mvc-configuration]] |
|
=== Switch off the Default MVC configuration |
|
The easiest way to take complete control over MVC configuration is to provide your own |
|
`@Configuration` with the `@EnableWebMvc` annotation. This will leave all MVC |
|
configuration in your hands. |
|
|
|
|
|
|
|
[[howto-customize-view-resolvers]] |
|
=== Customize ViewResolvers |
|
A `ViewResolver` is a core component of Spring MVC, translating view names in |
|
`@Controller` to actual `View` implementations. Note that `ViewResolvers` are mainly |
|
used in UI applications, rather than REST-style services (a `View` is not used to render |
|
a `@ResponseBody`). There are many implementations of `ViewResolver` to choose from, and |
|
Spring on its own is not opinionated about which ones you should use. Spring Boot, on the |
|
other hand, installs one or two for you depending on what it finds on the classpath and |
|
in the application context. The `DispatcherServlet` uses all the resolvers it finds in |
|
the application context, trying each one in turn until it gets a result, so if you are |
|
adding your own you have to be aware of the order and in which position your resolver is |
|
added. |
|
|
|
`WebMvcAutoConfiguration` adds the following `ViewResolvers` to your context: |
|
|
|
* An `InternalResourceViewResolver` with bean id ``defaultViewResolver''. This one locates |
|
physical resources that can be rendered using the `DefaultServlet` (e.g. static |
|
resources and JSP pages if you are using those). It applies a prefix and a suffix to the |
|
view name and then looks for a physical resource with that path in the servlet context |
|
(defaults are both empty, but accessible for external configuration via |
|
`spring.view.prefix` and `spring.view.suffix`). It can be overridden by providing a |
|
bean of the same type. |
|
|
|
* A `BeanNameViewResolver` with id ``beanNameViewResolver''. This is a useful member of the |
|
view resolver chain and will pick up any beans with the same name as the `View` being |
|
resolved. It can be overridden by providing a bean of the same type, but it's unlikely |
|
you will need to do that. |
|
|
|
* A `ContentNegotiatingViewResolver` with id ``viewResolver'' is only added if there *are* |
|
actually beans of type `View` present. This is a ``master'' resolver, delegating to all |
|
the others and attempting to find a match to the ``Accept'' HTTP header sent by the |
|
client. There is a useful |
|
https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about `ContentNegotiatingViewResolver`] |
|
that you might like to study to learn more, and also look at the source code for detail. |
|
You can switch off the auto-configured |
|
`ContentNegotiatingViewResolver` by defining a bean named ``viewResolver''. |
|
|
|
* If you use Thymeleaf you will also have a `ThymeleafViewResolver` with id |
|
``thymeleafViewResolver''. It looks for resources by surrounding the view name with a |
|
prefix and suffix (externalized to `spring.thymeleaf.prefix` and |
|
`spring.thymeleaf.suffix`, defaults ``classpath:/templates/'' and ``.html'' |
|
respectively). It can be overridden by providing a bean of the same name. |
|
|
|
Checkout {sc-spring-boot-autoconfigure}/web/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] |
|
and {sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`] |
|
|
|
|
|
|
|
[[howto-logging]] |
|
== Logging |
|
|
|
|
|
|
|
[[howto-configure-logback-for-loggin]] |
|
=== Configure Logback for logging |
|
Spring Boot has no mandatory logging dependence, except for the `commons-logging` API, of |
|
which there are many implementations to choose from. To use http://logback.qos.ch[Logback] |
|
you need to include it, and some bindings for `commons-logging` on the classpath. The |
|
simplest way to do that is through the starter poms which all depend on |
|
`spring-boot-starter-logging`. For a web application you only need |
|
`spring-boot-starter-web` since it depends transitively on the logging starter. |
|
For example, using Maven: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-web</artifactId> |
|
</dependency> |
|
---- |
|
|
|
Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on |
|
the content of the classpath. If Logback is available it is the first choice. So if you |
|
put a `logback.xml` in the root of your classpath it will be picked up from there. Spring |
|
Boot provides a default base configuration that you can include if you just want to set |
|
levels, e.g. |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<?xml version="1.0" encoding="UTF-8"?> |
|
<configuration> |
|
<include resource="org/springframework/boot/logging/logback/base.xml"/> |
|
<logger name="org.springframework.web" level="DEBUG"/> |
|
</configuration> |
|
---- |
|
|
|
If you look at the default `logback.xml` in the spring-boot jar you will see that it uses |
|
some useful System properties which the `LoggingSystem` takes care of creating for you. |
|
These are: |
|
|
|
* `${PID}` the current process ID. |
|
* `${LOG_FILE}` if `logging.file` was set in Boot's external configuration. |
|
* `${LOG_PATH}` if `logging.path` was set (representing a directory for |
|
log files to live in). |
|
|
|
Spring Boot also provides some nice ANSI colour terminal output on a console (but not in |
|
a log file) using a custom Logback converter. See the default `base.xml` configuration |
|
for details. |
|
|
|
If Groovy is on the classpath you should be able to configure Logback with |
|
`logback.groovy` as well (it will be given preference if present). |
|
|
|
|
|
|
|
[[howto-configure-log4j-for-logging]] |
|
=== Configure Log4j for logging |
|
Spring Boot supports http://logging.apache.org/log4j[Log4j] for logging |
|
configuration, but it has to be on the classpath. If you are using the starter poms for |
|
assembling dependencies that means you have to exclude logback and then include log4j |
|
instead. If you aren't using the starter poms then you need to provide `commons-logging` |
|
(at least) in addition to Log4j. |
|
|
|
The simplest path to using Log4j is probably through the starter poms, even though it |
|
requires some jiggling with excludes, e.g. in Maven: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-web</artifactId> |
|
</dependency> |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter</artifactId> |
|
<exclusions> |
|
<exclusion> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-logging</artifactId> |
|
</exclusion> |
|
</exclusions> |
|
</dependency> |
|
<dependency> |
|
<groupId>org.springframework.boot</groupId> |
|
<artifactId>spring-boot-starter-log4j</artifactId> |
|
</dependency> |
|
---- |
|
|
|
NOTE: The use of the log4j starter gathers together the dependencies for common logging |
|
requirements (e.g. including having Tomcat use `java.util.logging` but configure the |
|
output using Log4j). See the Actuator Log4j Sample for more detail and to see it in |
|
action. |
|
|
|
|
|
|
|
[[howto-data-access]] |
|
== Data Access |
|
|
|
|
|
|
|
[[howto-configure-a-datasource]] |
|
=== Configure a DataSource |
|
To override the default settings just define a `@Bean` of your own of type `DataSource`. |
|
See '<<spring-boot-features.adoc#boot-features-configure-datasource>>' in the |
|
``Spring Boot features'' section and the |
|
{sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`] |
|
class for more details. |
|
|
|
|
|
|
|
[[howto-use-spring-data-repositories]] |
|
=== Use Spring Data repositories |
|
Spring Data can create implementations for you of `@Repository` interfaces of various |
|
flavours. Spring Boot will handle all of that for you as long as those `@Repositories` |
|
are included in the same package (or a sub-package) of your `@EnableAutoConfiguration` |
|
class. |
|
|
|
For many applications all you will need is to put the right Spring Data dependencies on |
|
your classpath (there is a `spring-boot-starter-data-jpa` for JPA and a |
|
`spring-boot-starter-data-mongodb` for Mongodb), create some repository interfaces to handle your |
|
`@Entity` objects. Examples are in the {github-code}/spring-boot-samples/spring-boot-sample-data-jpa[JPA sample] |
|
or the {github-code}/spring-boot-samples/spring-boot-sample-data-mongodb[Mongodb sample]. |
|
|
|
Spring Boot tries to guess the location of your `@Repository` definitions, based on the |
|
`@EnableAutoConfiguration` it finds. To get more control, use the `@EnableJpaRepositories` |
|
annotation (from Spring Data JPA). |
|
|
|
|
|
|
|
[[howto-separate-entity-definitions-from-spring-configuration]] |
|
=== Separate @Entity definitions from Spring configuration |
|
Spring Boot tries to guess the location of your `@Entity` definitions, based on the |
|
`@EnableAutoConfiguration` it finds. To get more control, you can use the `@EntityScan` |
|
annotation, e.g. |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@Configuration |
|
@EnableAutoConfiguration |
|
@EntityScan(basePackageClasses=City.class) |
|
public class Application { |
|
|
|
//... |
|
|
|
} |
|
---- |
|
|
|
|
|
|
|
[[howto-configure-jpa-properties]] |
|
=== Configure JPA properties |
|
Spring Data JPA already provides some vendor-independent configuration options (e.g. |
|
for SQL logging) and Spring Boot exposes those, and a few more for hibernate as external |
|
configuration properties. The most common options to set are: |
|
|
|
[indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
spring.jpa.hibernate.ddl-auto: create-drop |
|
spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy |
|
spring.jpa.database: H2 |
|
spring.jpa.show-sql: true |
|
---- |
|
|
|
(Because of relaxed data binding hyphens or underscores should work equally well as |
|
property keys.) The `ddl-auto` setting is a special case in that it has different |
|
defaults depending on whether you are using an embedded database (`create-drop`) or not |
|
(`none`). In addition all properties in `spring.jpa.properties.*` are passed through as |
|
normal JPA properties (with the prefix stripped) when the local `EntityManagerFactory` is |
|
created. |
|
|
|
See {sc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{sc-ext}[`HibernateJpaAutoConfiguration`] |
|
and {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBaseConfiguration`] |
|
for more details. |
|
|
|
|
|
|
|
[[howto-use-custom-entity-manager]] |
|
=== Use a custom EntityManagerFactory |
|
To take full control of the configuration of the `EntityManagerFactory`, you need to add |
|
a `@Bean` named "entityManagerFactory". To avoid eager initialization of JPA |
|
infrastructure, Spring Boot auto-configuration does not switch on its entity manager |
|
based on the presence of a bean of that type. Instead it has to do it by name. |
|
|
|
|
|
|
|
[[howto-use-traditional-persistence-xml]] |
|
=== Use a traditional persistence.xml |
|
Spring doesn't require the use of XML to configure the JPA provider, and Spring Boot |
|
assumes you want to take advantage of that feature. If you prefer to use `persistence.xml` |
|
then you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with |
|
id "entityManagerFactory", and set the persistence unit name there. |
|
|
|
See |
|
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java[`JpaBaseConfiguration`] |
|
for the default settings. |
|
|
|
|
|
|
|
[[howto-database-initialization]] |
|
== Database initialization |
|
An SQL database can be initialized in different ways depending on what your stack is. Or |
|
of course you can do it manually as long as the database is a separate process. |
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-jpa]] |
|
=== Initialize a database using JPA |
|
JPA has features for DDL generation, and these can be set up to run on startup against the |
|
database. This is controlled through two external properties: |
|
|
|
* `spring.jpa.generate-ddl` (boolean) switches the feature on and off and is vendor |
|
independent. |
|
* `spring.jpa.hibernate.ddl-auto` (enum) is a Hibernate feature that controls the |
|
behavior in a more fine-grained way. See below for more detail. |
|
|
|
|
|
|
|
[[howto-initialize-a-database-using-hibernate]] |
|
=== Initialize a database using Hibernate |
|
You can set `spring.jpa.hibernate.ddl-auto` explicitly and the standard Hibernate property |
|
values are `none`, `validate`, `update`, `create-drop`. Spring Boot chooses a default |
|
value for you based on whether it thinks your database is embedded (default `create-drop`) |
|
or not (default `none`). An embedded database is detected by looking at the `Connection` |
|
type: `hsqldb`, `h2` and `derby` are embedded, the rest are not. Be careful when switching |
|
from in-memory to a ``real'' database that you don't make assumptions about the existence of |
|
the tables and data in the new platform. You either have to set `ddl-auto` explicitly, or |
|
use one of the other mechanisms to initialize the database. |
|
|
|
In addition, a file named `import.sql` in the root of the classpath will be executed on |
|
startup. This can be useful for demos and for testing if you are careful, but probably |
|
not something you want to be on the classpath in production. It is a Hibernate feature |
|
(nothing to do with Spring). |
|
|
|
|
|
|
|
[[howto-intialize-a-database-using-spring-jdbc]] |
|
=== Initialize a database using Spring JDBC |
|
Spring JDBC has a `DataSource` initializer feature. Spring Boot enables it by default and |
|
loads SQL from the standard locations `schema.sql` and `data.sql` (in the root of the |
|
classpath). In addition Spring Boot will load a file `schema-${platform}.sql` where |
|
`platform` is the value of `spring.datasource.platform`, e.g. you might choose to set |
|
it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, |
|
`postgresql` etc.). Spring Boot enables the failfast feature of the Spring JDBC |
|
initializer by default, so if the scripts cause exceptions the application will fail |
|
to start. |
|
|
|
To disable the failfast you can set `spring.datasource.continueOnError=true`. This can be |
|
useful once an application has matured and been deployed a few times, since the scripts |
|
can act as ``poor man's migrations'' -- inserts that fail mean that the data is already |
|
there, so there would be no need to prevent the application from running, for instance. |
|
|
|
|
|
|
|
[[howto-initialize-a-spring-batch-database]] |
|
=== Initialize a Spring Batch database |
|
If you are using Spring Batch then it comes pre-packaged with SQL initialization scripts |
|
for most popular database platforms. Spring Boot will detect your database type, and |
|
execute those scripts by default, and in this case will switch the fail fast setting to |
|
false (errors are logged but do not prevent the application from starting). This is |
|
because the scripts are known to be reliable and generally do not contain bugs, so errors |
|
are ignorable, and ignoring them makes the scripts idempotent. You can switch off the |
|
initialization explicitly using `spring.batch.initializer.enabled=false`. |
|
|
|
|
|
|
|
[[howto-use-a-higher-level-database-migration-tool]] |
|
=== Use a higher level database migration tool |
|
Spring Boot works fine with higher level migration tools http://flywaydb.org/[Flyway] |
|
(SQL-based) and http://www.liquibase.org/[Liquibase] (XML). In general we prefer |
|
Flyway because it is easier on the eyes, and it isn't very common to need platform |
|
independence: usually only one or at most couple of platforms is needed. |
|
|
|
|
|
|
|
[[howto-batch-applications]] |
|
== Batch applications |
|
|
|
|
|
|
|
[[howto-execute-spring-batch-jobs-on-startup]] |
|
=== Execute Spring Batch jobs on startup |
|
Spring Batch auto configuration is enabled by adding `@EnableBatchProcessing` |
|
(from Spring Batch) somewhere in your context. |
|
|
|
By default it executes *all* `Jobs` in the application context on startup (see |
|
{sc-spring-boot-autoconfigure}/batch/JobLauncherCommandLineRunner.{sc-ext}[JobLauncherCommandLineRunner] |
|
for details). You can narrow down to a specific job or jobs by specifying |
|
`spring.batch.job.names` (comma separated job name patterns). |
|
|
|
If the application context includes a `JobRegistry` then the jobs in |
|
`spring.batch.job.names` are looked up in the registry instead of being autowired from the |
|
context. This is a common pattern with more complex systems where multiple jobs are |
|
defined in child contexts and registered centrally. |
|
|
|
See |
|
{sc-spring-boot-autoconfigure}/batch/BatchAutoConfiguration.{sc-ext}[BatchAutoConfiguration] |
|
and |
|
https://github.com/spring-projects/spring-batch/blob/master/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.java[@EnableBatchProcessing] |
|
for more details. |
|
|
|
|
|
|
|
[[howto-actuator]] |
|
== Actuator |
|
|
|
|
|
|
|
[[howto-change-the-http-port-or-address-of-the-actuator-endpoints]] |
|
=== Change the HTTP port or address of the actuator endpoints |
|
In a standalone application the Actuator HTTP port defaults to the same as the main HTTP |
|
port. To make the application listen on a different port set the external property |
|
`management.port`. To listen on a completely different network address (e.g. if you have |
|
an internal network for management and an external one for user applications) you can |
|
also set `management.address` to a valid IP address that the server is able to bind to. |
|
|
|
For more detail look at the |
|
{sc-spring-boot-actuator}/autoconfigure/ManagementServerProperties.{sc-ext}[`ManagementServerProperties`] |
|
source code and |
|
'<<production-ready-features.adoc#production-ready-customizing-management-server-port>>' |
|
in the ``Production-ready features'' section. |
|
|
|
|
|
|
|
[[howto-customize-the-whitelabel-error-page]] |
|
=== Customize the ``whitelabel'' error page |
|
The Actuator installs a ``whitelabel'' error page that you will see in browser client if |
|
you encounter a server error (machine clients consuming JSON and other media types should |
|
see a sensible response with the right error code). To switch it off you can set |
|
`error.whitelabel.enabled=false`, but normally in addition or alternatively to that you |
|
will want to add your own error page replacing the whitelabel one. If you are using |
|
Thymeleaf you can do this by adding an `error.html` template. In general what you need is |
|
a `View` that resolves with a name of `error`, and/or a `@Controller` that handles the |
|
`/error` path. Unless you replaced some of the default configuration you should find a |
|
`BeanNameViewResolver` in your `ApplicationContext` so a `@Bean` with id `error` would be |
|
a simple way of doing that. |
|
Look at {sc-spring-boot-actuator}/autoconfigure/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] for more options. |
|
|
|
|
|
|
|
[[howto-security]] |
|
== Security |
|
|
|
|
|
[[howto-switch-off-spring-boot-security-configuration]] |
|
=== Switch off the Spring Boot security configuration |
|
If you define a `@Configuration` with `@EnableWebSecurity` anywhere in your application |
|
it will switch off the default webapp security settings in Spring Boot. To tweak the |
|
defaults try setting properties in `security.*` (see |
|
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`] |
|
for details of available settings) and `SECURITY` section of |
|
<<common-application-properties-security,Common application properties>>. |
|
|
|
|
|
|
|
[[howto-change-the-authenticationmanager-and-add-user-accounts]] |
|
=== Change the AuthenticationManager and add user accounts |
|
If you provide a `@Bean` of type `AuthenticationManager` the default one will not be |
|
created, so you have the full feature set of Spring Security available (e.g. |
|
http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication[various authentication options]). |
|
|
|
Spring Security also provides a convenient `AuthenticationManagerBuilder` which can be |
|
used to build an `AuthenticationManager` with common options. The recommended way to |
|
use this in a webapp is to inject it into a void method in a |
|
`WebSecurityConfigurerAdapter`, e.g. |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@Configuration |
|
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { |
|
|
|
@Autowired |
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { |
|
auth.inMemoryAuthentication() |
|
.withUser("barry").password("password").roles("USER"); // ... etc. |
|
} |
|
|
|
// ... other stuff for application security |
|
|
|
} |
|
---- |
|
|
|
You will get the best results if you put this in a nested class, or a standalone class |
|
(i.e. not mixed in with a lot of other `@Beans` that might be allowed to influence the |
|
order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample] |
|
is a useful template to follow. |
|
|
|
|
|
|
|
[[howto-enable-https]] |
|
=== Enable HTTPS when running behind a proxy server |
|
Ensuring that all your main endpoints are only available over HTTPS is an important |
|
chore for any application. If you are using Tomcat as a servlet container, then |
|
Spring Boot will add Tomcat's own `RemoteIpValve` automatically if it detects some |
|
environment settings, and you should be able to rely on the `HttpServletRequest` to |
|
report whether it is secure or not (even downstream of a proxy server that handles the |
|
real SSL termination). The standard behavior is determined by the presence or absence of |
|
certain request headers (`x-forwarded-for` and `x-forwarded-proto`), whose names are |
|
conventional, so it should work with most front end proxies. You can switch on the valve |
|
by adding some entries to `application.properties`, e.g. |
|
|
|
[source,properties,indent=0] |
|
---- |
|
server.tomcat.remote_ip_header=x-forwarded-for |
|
server.tomcat.protocol_header=x-forwarded-proto |
|
---- |
|
|
|
(The presence of either of those properties will switch on the valve. Or you can add the |
|
`RemoteIpValve` yourself by adding a `TomcatEmbeddedServletContainerFactory` bean.) |
|
|
|
Spring Security can also be configured to require a secure channel for all (or some |
|
requests). To switch that on in a Spring Boot application you just need to set |
|
`security.require_https` to `true` in `application.properties`. |
|
|
|
|
|
|
|
[[howto-hotswapping]] |
|
== Hot swapping |
|
|
|
|
|
|
|
[[howto-reload-static-content]] |
|
=== Reload static content |
|
There are several options for hot reloading. Running in an IDE (especially with debugging |
|
on) is a good way to do development (all modern IDEs allow reloading of static resources |
|
and usually also hot-swapping of Java class changes). The |
|
<<build-tool-plugins.adoc#build-tool-plugins, Maven and Gradle plugins>> also |
|
support running from the command line with reloading of static files. You can use that |
|
with an external css/js compiler process if you are writing that code with higher level |
|
tools. |
|
|
|
|
|
|
|
[[howto-reload-thymeleaf-content]] |
|
=== Reload Thymeleaf templates without restarting the container |
|
If you are using Thymeleaf, then set `spring.thymeleaf.cache` to `false`. See |
|
{sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`] |
|
for other template customization options. |
|
|
|
|
|
|
|
[[howto-reload-java-classes-without-restarting]] |
|
=== Reload Java classes without restarting the container |
|
Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if you make a |
|
change that doesn't affect class or method signatures it should reload cleanly with no |
|
side effects. |
|
|
|
https://github.com/spring-projects/spring-loaded[Spring Loaded] goes a little further in |
|
that it can reload class definitions with changes in the method signatures. With some |
|
customization it can force an `ApplicationContext` to refresh itself (but there is no |
|
general mechanism to ensure that would be safe for a running application anyway, so it |
|
would only ever be a development time trick probably). |
|
|
|
|
|
|
|
[[howto-build]] |
|
== Build |
|
|
|
|
|
|
|
[[howto-customize-dependency-versions-with-maven]] |
|
=== Customize dependency versions with Maven |
|
If you use a Maven build that inherits from `spring-boot-starter-parent` but you want |
|
to override a specific third-party dependency you can add appropriate `<properties>` |
|
elements. Browse the {github-code}/spring-boot-dependencies/pom.xml[`spring-dependencies`] |
|
POM for a complete list of properties. For example, to pick a different `slf4j` version |
|
you would add the following: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<properties> |
|
<slf4j.version>1.7.5<slf4j.version> |
|
</properties> |
|
---- |
|
|
|
WARNING: Each Spring Boot release is designed and tested against a specific set of |
|
third-party dependencies. Overriding versions may cause compatibilty issues. |
|
|
|
|
|
|
|
[[howto-remote-debug-maven-run]] |
|
=== Remote debug a Spring Boot application started with Maven |
|
To attach a remote debugger to a Spring Boot application started with Maven you can use |
|
the `mvnDebug` command rather than `mvn`. For example: |
|
|
|
[indent=0] |
|
---- |
|
$ mvnDebug spring-boot:run |
|
---- |
|
|
|
You can now attach a remote debugger to your running application on port `8000`. |
|
|
|
|
|
|
|
[[howto-build-an-executable-archive-with-ant]] |
|
=== Build an executable archive with Ant |
|
To build with Ant you need to grab dependencies, compile and then create a jar or war |
|
archive as normal. To make it executable: |
|
|
|
. Use the appropriate launcher as a `Main-Class`, e.g. `JarLauncher` for a jar file, and |
|
specify the other properties it needs as manifest entries, principally a `Start-Class`. |
|
|
|
. Add the runtime dependencies in a nested "lib" directory (for a jar) and the |
|
`provided` (embedded container) dependencies in a nested `lib-provided` directory. |
|
Remember *not* to compress the entries in the archive. |
|
|
|
. Add the `spring-boot-loader` classes at the root of the archive (so the `Main-Class` |
|
is available). |
|
|
|
Example: |
|
|
|
[source,xml,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
<target name="build" depends="compile"> |
|
<copy todir="target/classes/lib"> |
|
<fileset dir="lib/runtime" /> |
|
</copy> |
|
<jar destfile="target/spring-boot-sample-actuator-${spring-boot.version}.jar" compress="false"> |
|
<fileset dir="target/classes" /> |
|
<fileset dir="src/main/resources" /> |
|
<zipfileset src="lib/loader/spring-boot-loader-jar-${spring-boot.version}.jar" /> |
|
<manifest> |
|
<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" /> |
|
<attribute name="Start-Class" value="${start-class}" /> |
|
</manifest> |
|
</jar> |
|
</target> |
|
---- |
|
|
|
The Actuator Sample has a `build.xml` that should work if you run it with |
|
|
|
[indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
$ ant -lib <path_to>/ivy-2.2.jar |
|
---- |
|
|
|
after which you can run the application with |
|
|
|
[indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
$ java -jar target/*.jar |
|
---- |
|
|
|
|
|
|
|
[[howto-traditional-deployment]] |
|
== Traditional deployment |
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file]] |
|
=== Create a deployable war file |
|
Use the `SpringBootServletInitializer` base class, which is picked up by Spring's |
|
Servlet 3.0 support on deployment. Add an extension of that to your project and build a |
|
war file as normal. For more detail, see the |
|
http://spring.io/guides/gs/convert-jar-to-war[``Converting a jar Project to a war''] guide |
|
on the spring.io website and the sample below. |
|
|
|
The war file can also be executable if you use the Spring Boot build tools. In that case |
|
the embedded container classes (to launch Tomcat for instance) have to be added to the |
|
war in a `lib-provided` directory. The tools will take care of that as long as the |
|
dependencies are marked as "provided" in Maven or Gradle. Here's a Maven example |
|
{github-code}/spring-boot-samples/spring-boot-sample-traditional/pom.xml[in the Boot Samples]. |
|
|
|
|
|
|
|
[[howto-create-a-deployable-war-file-for-older-containers]] |
|
=== Create a deployable war file for older servlet containers |
|
Older Servlet containers don't have support for the `ServletContextInitializer` bootstrap |
|
process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers |
|
but you are going to need to add a `web.xml` to your application and configure it to load |
|
an `ApplicationContext` via a `DispatcherServlet`. |
|
|
|
|
|
|
|
[[howto-convert-an-existing-application-to-spring-boot]] |
|
=== Convert an existing application to Spring Boot |
|
For a non-web application it should be easy (throw away the code that creates your |
|
`ApplicationContext` and replace it with calls to `SpringApplication` or |
|
`SpringApplicationBuilder`). Spring MVC web applications are generally amenable to first |
|
creating a deployable war application, and then migrating it later to an executable war |
|
and/or jar. Useful reading is in the http://spring.io/guides/gs/convert-jar-to-war/[Getting |
|
Started Guide on Converting a jar to a war]. |
|
|
|
Create a deployable war by extending `SpringBootServletInitializer` (e.g. in a class |
|
called `Application`), and add the Spring Boot `@EnableAutoConfiguration` annotation. |
|
Example: |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
@Configuration |
|
@EnableAutoConfiguration |
|
@ComponentScan |
|
public class Application extends SpringBootServletInitializer { |
|
|
|
@Override |
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { |
|
return application.sources(Application.class); |
|
} |
|
|
|
} |
|
---- |
|
|
|
Remember that whatever you put in the `sources` is just a Spring `ApplicationContext` and |
|
normally anything that already works should work here. There might be some beans you can |
|
remove later and let Spring Boot provide its own defaults for them, but it should be |
|
possible to get something working first. |
|
|
|
Static resources can be moved to `/public` (or `/static` or `/resources` or |
|
`/META-INF/resources`) in the classpath root. Same for `messages.properties` (Spring Boot |
|
detects this automatically in the root of the classpath). |
|
|
|
Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further |
|
changes. If you have other features in your application, using other servlets or filters |
|
for instance, then you may need to add some configuration to your `Application` context, |
|
replacing those elements from the `web.xml` as follows: |
|
|
|
* A `@Bean` of type `Servlet` or `ServletRegistrationBean` installs that bean in the |
|
container as if it was a `<servlet/>` and `<servlet-mapping/>` in `web.xml`. |
|
* A `@Bean` of type `Filter` or `FilterRegistrationBean` behaves similarly (like a |
|
`<filter/>` and `<filter-mapping/>`. |
|
* An `ApplicationContext` in an XML file can be added to an `@Import` in your |
|
`Application`. Or simple cases where annotation configuration is heavily used already |
|
can be recreated in a few lines as `@Bean` definitions. |
|
|
|
Once the war is working we make it executable by adding a `main` method to our |
|
`Application`, e.g. |
|
|
|
[source,java,indent=0,subs="verbatim,quotes,attributes"] |
|
---- |
|
public static void main(String[] args) { |
|
SpringApplication.run(Application.class, args); |
|
} |
|
---- |
|
|
|
Applications can fall into more than one category: |
|
|
|
* Servlet 3.0 applications with no `web.xml`. |
|
* Applications with a `web.xml`. |
|
* Applications with a context hierarchy. |
|
* Applications without a context hierarchy. |
|
|
|
All of these should be amenable to translation, but each might require slightly different |
|
tricks. |
|
|
|
Servlet 3.0 applications might translate pretty easily if they already use the Spring |
|
Servlet 3.0 initializer support classes. Normally all the code from an existing |
|
`WebApplicationInitializer` can be moved into a `SpringBootServletInitializer`. If your |
|
existing application has more than one `ApplicationContext` (e.g. if it uses |
|
`AbstractDispatcherServletInitializer`) then you might be able to squash all your context |
|
sources into a single `SpringApplication`. The main complication you might encounter is if |
|
that doesn't work and you need to maintain the context hierarchy. See the |
|
<<howto-build-an-application-context-hierarchy, entry on building a hierarchy>> for |
|
examples. An existing parent context that contains web-specific features will usually |
|
need to be broken up so that all the `ServletContextAware` components are in the child |
|
context. |
|
|
|
Applications that are not already Spring applications might be convertible to a Spring |
|
Boot application, and the guidance above might help, but your mileage may vary.
|
|
|