| 
									
										
										
										
											2014-03-14 04:18:47 +08:00
										 |  |  | [[howto]] | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | = '`How-to`' guides | 
					
						
							| 
									
										
										
										
											2014-03-14 04:18:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [partintro] | 
					
						
							|  |  |  | -- | 
					
						
							| 
									
										
										
										
											2014-10-09 17:24:30 +08:00
										 |  |  | This section provides answers to some common '`how do I do that...`' type of questions | 
					
						
							| 
									
										
										
										
											2014-03-14 04:18:47 +08:00
										 |  |  | 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). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | We're also more than happy to extend this section; If you want to add a '`how-to`' you | 
					
						
							| 
									
										
										
										
											2014-03-14 04:18:47 +08:00
										 |  |  | can send us a {github-code}[pull request]. | 
					
						
							|  |  |  | -- | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-spring-boot-application]] | 
					
						
							|  |  |  | == Spring Boot application | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-02 19:11:50 +08:00
										 |  |  | [[howto-failure-analyzer]] | 
					
						
							|  |  |  | === Create your own FailureAnalyzer | 
					
						
							| 
									
										
										
										
											2016-10-02 13:00:47 +08:00
										 |  |  | {dc-spring-boot}/diagnostics/FailureAnalyzer.{dc-ext}[`FailureAnalyzer`] is a great way | 
					
						
							| 
									
										
										
										
											2016-09-02 19:11:50 +08:00
										 |  |  | to intercept an exception on startup and turn it into a human-readable message, wrapped | 
					
						
							| 
									
										
										
										
											2016-10-02 13:00:47 +08:00
										 |  |  | into a {dc-spring-boot}/diagnostics/FailureAnalysis.{dc-ext}[`FailureAnalysis`]. Spring | 
					
						
							| 
									
										
										
										
											2016-09-02 19:11:50 +08:00
										 |  |  | Boot provides such analyzer for application context related exceptions, JSR-303 | 
					
						
							|  |  |  | validations and more. It is actually very easy to create your own. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `AbstractFailureAnalyzer` is a convenient extension of `FailureAnalyzer` that checks the | 
					
						
							|  |  |  | presence of a specified exception type in the exception to handle. You can extend from | 
					
						
							|  |  |  | that so that your implementation gets a chance to handle the exception only when it is | 
					
						
							|  |  |  | actually present. If for whatever reason you can't handle the exception, return `null` | 
					
						
							| 
									
										
										
										
											2016-10-02 13:00:47 +08:00
										 |  |  | to give another implementation a chance to handle the exception. | 
					
						
							| 
									
										
										
										
											2016-09-02 19:11:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | `FailureAnalyzer` implementations are to be registered in a `META-INF/spring.factories`: | 
					
						
							|  |  |  | the following registers `ProjectConstraintViolationFailureAnalyzer`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	org.springframework.boot.diagnostics.FailureAnalyzer=\ | 
					
						
							|  |  |  | 	com.example.ProjectConstraintViolationFailureAnalyzer | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[howto-troubleshoot-auto-configuration]] | 
					
						
							|  |  |  | === Troubleshoot auto-configuration | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | The Spring Boot auto-configuration tries its best to '`do the right thing`', but | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | sometimes things fail and it can be hard to tell why. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-18 21:47:20 +08:00
										 |  |  | There is a really useful `ConditionEvaluationReport` available in any Spring Boot | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | `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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 12:36:47 +08:00
										 |  |  | Many more questions can be answered by looking at the source code and the Javadoc. Some | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | rules of thumb: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 03:40:34 +08:00
										 |  |  | * Look for classes called `+*AutoConfiguration+` and read their sources, in particular the | 
					
						
							|  |  |  |   `+@Conditional*+` annotations to find out what features they enable and when. Add | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   `--debug` to the command line or a System property `-Ddebug` to get a log on the | 
					
						
							| 
									
										
										
										
											2015-10-27 12:21:26 +08:00
										 |  |  |   console of all the auto-configuration decisions that were made in your app. In a running | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  |   Actuator app look at the `autoconfig` endpoint ('`/autoconfig`' or the JMX equivalent) for | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   the same information. | 
					
						
							|  |  |  | * Look for classes that are `@ConfigurationProperties` (e.g. | 
					
						
							| 
									
										
										
										
											2014-04-16 17:48:36 +08:00
										 |  |  |   {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`]) | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   and read from there the available external configuration options. The | 
					
						
							|  |  |  |   `@ConfigurationProperties` has a `name` attribute which acts as a prefix to external | 
					
						
							| 
									
										
										
										
											2014-04-04 15:54:20 +08:00
										 |  |  |   properties, thus `ServerProperties` has `prefix="server"` and its configuration properties | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   are `server.port`, `server.address` etc. In a running Actuator app look at the | 
					
						
							|  |  |  |   `configprops` endpoint. | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  | * Look for use of `RelaxedPropertyResolver` to pull configuration values explicitly out of the | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   `Environment`. It often is used with a prefix. | 
					
						
							|  |  |  | * Look for `@Value` annotations that bind directly to the `Environment`. This is less | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  |   flexible than the `RelaxedPropertyResolver` approach, but does allow some relaxed binding, | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  |   response to SpEL expressions, normally evaluated with placeholders resolved from the | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   `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`. | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | * Declaratively for all applications by adding a `META-INF/spring.factories` and packaging | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | _<<spring-boot-features.adoc#boot-features-application-events-and-listeners>>_ in the | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | '`Spring Boot features`' section for a complete list. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-20 21:29:38 +08:00
										 |  |  | It is also possible to customize the `Environment` before the application context is | 
					
						
							|  |  |  | refreshed using `EnvironmentPostProcessor`. Each implementation should be registered in | 
					
						
							|  |  |  | `META-INF/spring.factories`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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` | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | hierarchies. See _<<spring-boot-features.adoc#boot-features-fluent-builder-api>>_ | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | in the '`Spring Boot features`' section for more information. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2015-11-30 22:08:40 +08:00
										 |  |  | `setWebEnvironment(false)` on your `SpringApplication` instance, or set the | 
					
						
							|  |  |  | `applicationContextClass` property (through the Java API or with external properties). | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-24 19:55:56 +08:00
										 |  |  | [[howto-automatic-expansion]] | 
					
						
							|  |  |  | === Automatically expand properties at build time | 
					
						
							|  |  |  | Rather than hardcoding some properties that are also specified in your project's build | 
					
						
							|  |  |  | configuration, you can automatically expand them using the existing build configuration | 
					
						
							|  |  |  | instead. This is possible in both Maven and Gradle. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-automatic-expansion-maven]] | 
					
						
							|  |  |  | ==== Automatic property expansion using Maven | 
					
						
							|  |  |  | You can automatically expand properties from the Maven project using resource | 
					
						
							|  |  |  | filtering. If you use the `spring-boot-starter-parent` you can then refer to your | 
					
						
							|  |  |  | Maven '`project properties`' via `@..@` placeholders, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	app.encoding=@project.build.sourceEncoding@ | 
					
						
							|  |  |  | 	app.java.version=@java.version@ | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TIP: The `spring-boot:run` can add `src/main/resources` directly to the classpath | 
					
						
							|  |  |  | (for hot reloading purposes) if you enable the `addResources` flag. This circumvents | 
					
						
							|  |  |  | the resource filtering and this feature. You can use the `exec:java` goal instead | 
					
						
							|  |  |  | or customize the plugin's configuration, see the | 
					
						
							|  |  |  | {spring-boot-maven-plugin-site}/usage.html[plugin usage page] for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you don't use the starter parent, in your `pom.xml` you need (inside the `<build/>` | 
					
						
							|  |  |  | element): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-01-04 08:59:53 +08:00
										 |  |  | 	<resources> | 
					
						
							|  |  |  | 		<resource> | 
					
						
							|  |  |  | 			<directory>src/main/resources</directory> | 
					
						
							|  |  |  | 			<filtering>true</filtering> | 
					
						
							|  |  |  | 		</resource> | 
					
						
							|  |  |  | 	</resources> | 
					
						
							| 
									
										
										
										
											2016-03-24 19:55:56 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | and (inside `<plugins/>`): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<plugin> | 
					
						
							|  |  |  | 		<groupId>org.apache.maven.plugins</groupId> | 
					
						
							|  |  |  | 		<artifactId>maven-resources-plugin</artifactId> | 
					
						
							|  |  |  | 		<version>2.7</version> | 
					
						
							|  |  |  | 		<configuration> | 
					
						
							|  |  |  | 			<delimiters> | 
					
						
							|  |  |  | 				<delimiter>@</delimiter> | 
					
						
							|  |  |  | 			</delimiters> | 
					
						
							|  |  |  | 			<useDefaultDelimiters>false</useDefaultDelimiters> | 
					
						
							|  |  |  | 		</configuration> | 
					
						
							|  |  |  | 	</plugin> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: The `useDefaultDelimiters` property is important if you are using standard Spring | 
					
						
							|  |  |  | placeholders in your configuration (e.g. `${foo}`). These may be expanded by the build if | 
					
						
							|  |  |  | that property is not set to `false`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-automatic-expansion-gradle]] | 
					
						
							|  |  |  | ==== Automatic property expansion using Gradle | 
					
						
							|  |  |  | You can automatically expand properties from the Gradle project by configuring the | 
					
						
							|  |  |  | Java plugin's `processResources` task to do so: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	processResources { | 
					
						
							|  |  |  | 		expand(project.properties) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can then refer to your Gradle project's properties via placeholders, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	app.name=${name} | 
					
						
							|  |  |  | 	app.description=${description} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: Gradle's `expand` method uses Groovy's `SimpleTemplateEngine` which transforms | 
					
						
							|  |  |  | `${..}` tokens. The `${..}` style conflicts with Spring's own property placeholder | 
					
						
							|  |  |  | mechanism. To use Spring property placeholders together with automatic expansion | 
					
						
							|  |  |  | the Spring property placeholders need to be escaped like `\${..}`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-10-10 03:40:34 +08:00
										 |  |  | configuration using properties in `+spring.main.*+`. E.g. in `application.properties` you | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | might have. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2016-04-08 14:10:48 +08:00
										 |  |  | 	spring.main.web-environment=false | 
					
						
							|  |  |  | 	spring.main.banner-mode=off | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | and then the Spring Boot banner will not be printed on startup, and the application will | 
					
						
							|  |  |  | not be a web application. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 02:26:15 +08:00
										 |  |  | NOTE: The example above also demonstrates how flexible binding allows the use of | 
					
						
							|  |  |  | underscores (`_`) as well as dashes (`-`) in property names. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-27 17:11:19 +08:00
										 |  |  | Properties defined in external configuration overrides the values specified via the Java | 
					
						
							|  |  |  | API with the notable exception of the sources used to create the `ApplicationContext`. Let's | 
					
						
							|  |  |  | consider this application | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	new SpringApplicationBuilder() | 
					
						
							| 
									
										
										
										
											2015-10-08 17:44:16 +08:00
										 |  |  | 		.bannerMode(Banner.Mode.OFF) | 
					
						
							| 
									
										
										
										
											2015-05-27 17:11:19 +08:00
										 |  |  | 		.sources(demo.MyApp.class) | 
					
						
							|  |  |  | 		.run(args); | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | used with the following configuration: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	spring.main.sources=com.acme.Config,com.acme.ExtraConfig | 
					
						
							| 
									
										
										
										
											2016-04-08 14:10:48 +08:00
										 |  |  | 	spring.main.banner-mode=console | 
					
						
							| 
									
										
										
										
											2015-05-27 17:11:19 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-18 22:55:59 +08:00
										 |  |  | The actual application will _now_ show the banner (as overridden by configuration) and use | 
					
						
							| 
									
										
										
										
											2015-06-18 22:55:28 +08:00
										 |  |  | three sources for the `ApplicationContext` (in that order): `demo.MyApp`, `com.acme.Config`, | 
					
						
							| 
									
										
										
										
											2015-05-27 17:11:19 +08:00
										 |  |  | `com.acme.ExtraConfig`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-04 02:57:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | defined order (see _<<spring-boot-features.adoc#boot-features-external-config>>_ in | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | the '`Spring Boot features`' section for the exact order). | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  | in this way have lower | 
					
						
							| 
									
										
										
										
											2015-12-12 15:57:25 +08:00
										 |  |  | priority than any added using the default locations (e.g. `application.properties`), system properties, environment variables or the command line. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | * `spring.config.location` (`SPRING_CONFIG_LOCATION`) is the file to load (e.g. a classpath | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | `application.properties` as described above. If YAML is used then files with the '`.yml`' | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | extension are also added to the list by default. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 00:05:36 +08:00
										 |  |  | Spring Boot logs the configuration files that are loaded at `DEBUG` level and the | 
					
						
							|  |  |  | candidates it has not found at `TRACE` level. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-29 03:07:45 +08:00
										 |  |  | See {sc-spring-boot}/context/config/ConfigFileApplicationListener.{sc-ext}[`ConfigFileApplicationListener`] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | for more detail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-use-short-command-line-arguments]] | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | === Use '`short`' command line arguments | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | 	server.port=${port:8080} | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 21:01:51 +08:00
										 |  |  | TIP: If you are inheriting from the `spring-boot-starter-parent` POM, the default filter | 
					
						
							|  |  |  | token of the `maven-resources-plugins` has been changed from `+${*}+` to `@` (i.e. | 
					
						
							| 
									
										
										
										
											2014-11-04 18:29:55 +08:00
										 |  |  | `@maven.token@` instead of `${maven.token}`) to prevent conflicts with Spring-style | 
					
						
							|  |  |  | placeholders. If you have enabled maven filtering for the `application.properties` | 
					
						
							|  |  |  | directly, you may want to also change the default filter token to use | 
					
						
							| 
									
										
										
										
											2014-03-19 02:35:11 +08:00
										 |  |  | http://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html#delimiters[other delimiters]. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | also add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | included if you use the `spring-boot-starter`). A YAML file is parsed to a Java | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | `Map<String,Object>` (like a JSON object), and Spring Boot flattens the map so that it | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | 	spring.application.name=cruncher | 
					
						
							|  |  |  | 	spring.datasource.driverClassName=com.mysql.jdbc.Driver | 
					
						
							|  |  |  | 	spring.datasource.url=jdbc:mysql://localhost/test | 
					
						
							|  |  |  | 	server.port=9000 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | See _<<spring-boot-features.adoc#boot-features-external-config-yaml>>_ in | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | the '`Spring Boot features`' section for more information | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | about YAML. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-set-active-spring-profiles]] | 
					
						
							|  |  |  | === Set the active Spring profiles | 
					
						
							| 
									
										
										
										
											2015-08-07 22:03:15 +08:00
										 |  |  | The Spring `Environment` has an API for this, but normally you would set a System property | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | (`spring.profiles.active`) or an OS environment variable (`SPRING_PROFILES_ACTIVE`). E.g. | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | launch your application with a `-D` argument (remember to put it before the main class | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 	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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | See _<<spring-boot-features.adoc#boot-features-profiles>>_ in | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | the '`Spring Boot features`' section for more information. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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 | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | other places) into an application at runtime. There is not (and technically cannot be) | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  | `RelaxedPropertyResolver`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-embedded-servlet-containers]] | 
					
						
							|  |  |  | == Embedded servlet containers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 23:45:44 +08:00
										 |  |  | [[howto-add-a-servlet-filter-or-listener]] | 
					
						
							|  |  |  | === Add a Servlet, Filter or Listener to an application | 
					
						
							|  |  |  | There are two ways to add `Servlet`, `Filter`, `ServletContextListener` and the other | 
					
						
							|  |  |  | listeners supported by the Servlet spec to your application. You can either provide | 
					
						
							|  |  |  | Spring beans for them, or enable scanning for Servlet components. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-add-a-servlet-filter-or-listener-as-spring-bean]] | 
					
						
							|  |  |  | ==== Add a Servlet, Filter or Listener using a Spring bean | 
					
						
							|  |  |  | To add a `Servlet`, `Filter`, or Servlet `*Listener` provide a `@Bean` definition for it. | 
					
						
							|  |  |  | This can be very useful when you want to inject configuration or dependencies. However, | 
					
						
							|  |  |  | you must 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. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 18:04:56 +08:00
										 |  |  | [NOTE] | 
					
						
							|  |  |  | ==== | 
					
						
							|  |  |  | If no `dispatcherType` is specified on a filter registration, it will match | 
					
						
							|  |  |  | `FORWARD`,`INCLUDE` and `REQUEST`. If async has been enabled, it will match `ASYNC` as | 
					
						
							|  |  |  | well. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you are migrating a filter that has no `dispatcher` element in `web.xml` you will | 
					
						
							|  |  |  | need to specify a `dispatcherType` yourself: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							|  |  |  | 	public FilterRegistrationBean myFilterRegistration() { | 
					
						
							|  |  |  | 		FilterRegistrationBean registration = new FilterRegistrationBean(); | 
					
						
							|  |  |  | 		registration.setDispatcherTypes(DispatcherType.REQUEST); | 
					
						
							|  |  |  | 		.... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return registration; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | ==== | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 21:15:52 +08:00
										 |  |  | [[howto-disable-registration-of-a-servlet-or-filter]] | 
					
						
							| 
									
										
										
										
											2015-08-17 23:45:44 +08:00
										 |  |  | ===== Disable registration of a Servlet or Filter | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | As <<howto-add-a-servlet-filter-or-listener-as-spring-bean,described above>> any `Servlet` | 
					
						
							| 
									
										
										
										
											2015-02-11 21:15:52 +08:00
										 |  |  | or `Filter` beans will be registered with the servlet container automatically. To disable | 
					
						
							|  |  |  | registration of a particular `Filter` or `Servlet` bean create a registration bean for it | 
					
						
							|  |  |  | and mark it as disabled. For example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-02-26 00:23:18 +08:00
										 |  |  | 	@Bean | 
					
						
							| 
									
										
										
										
											2015-02-11 21:15:52 +08:00
										 |  |  | 	public FilterRegistrationBean registration(MyFilter filter) { | 
					
						
							|  |  |  | 		FilterRegistrationBean registration = new FilterRegistrationBean(filter); | 
					
						
							|  |  |  | 		registration.setEnabled(false); | 
					
						
							|  |  |  | 		return registration; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-04 12:36:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 23:45:44 +08:00
										 |  |  | [[howto-add-a-servlet-filter-or-listener-using-scanning]] | 
					
						
							|  |  |  | ==== Add Servlets, Filters, and Listeners using classpath scanning | 
					
						
							|  |  |  | `@WebServlet`, `@WebFilter`, and `@WebListener` annotated classes can be automatically | 
					
						
							|  |  |  | registered with an embedded servlet container by annotating a `@Configuration` class | 
					
						
							|  |  |  | with `@ServletComponentScan` and specifying the package(s) containing the components | 
					
						
							|  |  |  | that you want to register. By default, `@ServletComponentScan` will scan from the package | 
					
						
							|  |  |  | of the annotated class. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 21:15:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | For more details look at _<<spring-boot-features.adoc#boot-features-customizing-embedded-containers>>_ | 
					
						
							| 
									
										
										
										
											2014-10-09 17:24:30 +08:00
										 |  |  | in the '`Spring Boot features`' section, or the | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/web/ServerProperties.{sc-ext}[`ServerProperties`] source | 
					
						
							|  |  |  | code. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 03:20:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ServletWebServerApplicationContext` via its `EmbeddedWebServer`. The best way to get | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | that and be sure that it has initialized is to add a `@Bean` of type | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ApplicationListener<ServletWebServerInitializedEvent>` and pull the container | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | out of the event when it is published. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 12:25:01 +08:00
										 |  |  | Tests that use `@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)` can | 
					
						
							| 
									
										
										
										
											2016-04-01 07:58:47 +08:00
										 |  |  | also inject the actual port into a field using the `@LocalServerPort` annotation. For | 
					
						
							|  |  |  | example: | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-18 16:37:04 +08:00
										 |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@RunWith(SpringJUnit4ClassRunner.class) | 
					
						
							| 
									
										
										
										
											2016-04-05 12:25:01 +08:00
										 |  |  | 	@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) | 
					
						
							| 
									
										
										
										
											2016-04-01 07:58:47 +08:00
										 |  |  | 	public class MyWebIntegrationTests { | 
					
						
							| 
									
										
										
										
											2014-03-18 16:37:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		@Autowired | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | 		ServletWebServerApplicationContext server; | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 21:19:55 +08:00
										 |  |  | 		@LocalServerPort | 
					
						
							| 
									
										
										
										
											2014-03-19 00:41:12 +08:00
										 |  |  | 		int port; | 
					
						
							| 
									
										
										
										
											2014-03-18 16:37:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-08 20:04:39 +08:00
										 |  |  | [NOTE] | 
					
						
							|  |  |  | ==== | 
					
						
							| 
									
										
										
										
											2016-03-14 21:19:55 +08:00
										 |  |  | `@LocalServerPort` is a meta-annotation for `@Value("${local.server.port}")`. Don't try | 
					
						
							|  |  |  | to inject the port in a regular application. As we just saw, the value is only set once | 
					
						
							|  |  |  | the container has initialized; contrary to a test, application code callbacks are | 
					
						
							|  |  |  | processed early (i.e. before the value is actually available). | 
					
						
							| 
									
										
										
										
											2015-09-08 20:04:39 +08:00
										 |  |  | ==== | 
					
						
							| 
									
										
										
										
											2014-07-30 04:06:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 04:37:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-23 00:51:51 +08:00
										 |  |  | [[howto-configure-ssl]] | 
					
						
							|  |  |  | === Configure SSL | 
					
						
							| 
									
										
										
										
											2014-10-10 03:40:34 +08:00
										 |  |  | SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, | 
					
						
							| 
									
										
										
										
											2014-07-23 00:51:51 +08:00
										 |  |  | typically in `application.properties` or `application.yml`. For example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-06-14 15:36:10 +08:00
										 |  |  | 	server.port=8443 | 
					
						
							|  |  |  | 	server.ssl.key-store=classpath:keystore.jks | 
					
						
							|  |  |  | 	server.ssl.key-store-password=secret | 
					
						
							| 
									
										
										
										
											2015-07-02 20:51:43 +08:00
										 |  |  | 	server.ssl.key-password=another-secret | 
					
						
							| 
									
										
										
										
											2014-07-23 00:51:51 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See {sc-spring-boot}/context/embedded/Ssl.{sc-ext}[`Ssl`] for details of all of the | 
					
						
							|  |  |  | supported properties. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 20:48:43 +08:00
										 |  |  | Using configuration like the example above means the application will no longer support | 
					
						
							|  |  |  | plain HTTP connector at port 8080. Spring Boot doesn't support the configuration of both | 
					
						
							|  |  |  | an HTTP connector and an HTTPS connector via `application.properties`. If you want to | 
					
						
							|  |  |  | have both then you'll need to configure one of them programmatically. It's recommended | 
					
						
							|  |  |  | to use `application.properties` to configure HTTPS as the HTTP connector is the easier of | 
					
						
							|  |  |  | the two to configure programmatically. See the | 
					
						
							|  |  |  | {github-code}/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors[`spring-boot-sample-tomcat-multi-connectors`] | 
					
						
							|  |  |  | sample project for an example. | 
					
						
							| 
									
										
										
										
											2014-07-23 00:51:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 03:20:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 23:59:47 +08:00
										 |  |  | [[howto-configure-accesslogs]] | 
					
						
							|  |  |  | === Configure Access Logging | 
					
						
							| 
									
										
										
										
											2017-04-27 16:41:39 +08:00
										 |  |  | Access logs can be configured for Tomcat, Undertow and Jetty via their respective | 
					
						
							|  |  |  | namespaces. | 
					
						
							| 
									
										
										
										
											2016-02-11 23:59:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | For instance, the following logs access on Tomcat with a | 
					
						
							| 
									
										
										
										
											2017-04-28 03:03:44 +08:00
										 |  |  | {tomcat-documentation}/config/valve.html#Access_Logging[custom pattern]. | 
					
						
							| 
									
										
										
										
											2016-02-11 23:59:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	server.tomcat.basedir=my-tomcat | 
					
						
							|  |  |  | 	server.tomcat.accesslog.enabled=true | 
					
						
							|  |  |  | 	server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: The default location for logs is a `logs` directory relative to the tomcat base dir | 
					
						
							|  |  |  | and said directory is a temp directory by default so you may want to fix Tomcat's base | 
					
						
							|  |  |  | directory or use an absolute path for the logs. In the example above, the logs will | 
					
						
							|  |  |  | be available in `my-tomcat/logs` relative to the working directory of the application. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Access logging for undertow can be configured in a similar fashion | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	server.undertow.accesslog.enabled=true | 
					
						
							|  |  |  | 	server.undertow.accesslog.pattern=%t %a "%r" %s (%D ms) | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Logs are stored in a `logs` directory relative to the working directory of the | 
					
						
							|  |  |  | application. This can be customized via `server.undertow.accesslog.directory`. | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 16:41:39 +08:00
										 |  |  | Finally, access logging for jetty can also be configured that way: | 
					
						
							| 
									
										
										
										
											2017-04-05 19:33:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	server.jetty.accesslog.enabled=true | 
					
						
							| 
									
										
										
										
											2017-04-27 20:19:16 +08:00
										 |  |  | 	server.jetty.accesslog.filename=/var/log/jetty-access.log | 
					
						
							| 
									
										
										
										
											2017-04-05 19:33:12 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 16:41:39 +08:00
										 |  |  | By default, logs will be redirected to `System.err`. For more details, please refer to | 
					
						
							| 
									
										
										
										
											2017-04-28 03:03:44 +08:00
										 |  |  | {jetty-documentation}/configuring-jetty-request-logs.html[the documentation]. | 
					
						
							| 
									
										
										
										
											2017-04-27 16:41:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-09 03:20:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-02 14:57:14 +08:00
										 |  |  | [[howto-use-behind-a-proxy-server]] | 
					
						
							|  |  |  | [[howto-use-tomcat-behind-a-proxy-server]] | 
					
						
							|  |  |  | === Use behind a front-end proxy server | 
					
						
							|  |  |  | Your application might need to send `302` redirects or render content with absolute links | 
					
						
							|  |  |  | back to itself. When running behind a proxy, the caller wants a link to the proxy, and not | 
					
						
							|  |  |  | to the physical address of the machine hosting your app. Typically such situations are | 
					
						
							|  |  |  | handled via a contract with the proxy, which will add headers to tell the back end how to | 
					
						
							|  |  |  | construct links to itself. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the proxy adds conventional `X-Forwarded-For` and `X-Forwarded-Proto` headers (most do | 
					
						
							|  |  |  | this out of the box) the absolute links should be rendered correctly as long as | 
					
						
							|  |  |  | `server.use-forward-headers` is set to `true` in your `application.properties`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: If your application is running in Cloud Foundry or Heroku the | 
					
						
							|  |  |  | `server.use-forward-headers` property will default to `true` if not specified. In all | 
					
						
							|  |  |  | other instances it defaults to `false`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-customize-tomcat-behind-a-proxy-server]] | 
					
						
							|  |  |  | ==== Customize Tomcat's proxy configuration | 
					
						
							|  |  |  | If you are using Tomcat you can additionally configure the names of the headers used to | 
					
						
							|  |  |  | carry "`forwarded`" information: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	server.tomcat.remote-ip-header=x-your-remote-ip-header | 
					
						
							|  |  |  | 	server.tomcat.protocol-header=x-your-protocol-header | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Tomcat is also configured with a default regular expression that matches internal | 
					
						
							|  |  |  | proxies that are to be trusted. By default, IP addresses in `10/8`, `192.168/16`, | 
					
						
							|  |  |  | `169.254/16` and `127/8` are trusted. You can customize the valve's configuration by | 
					
						
							|  |  |  | adding an entry to `application.properties`, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: The double backslashes are only required when you're using a properties file for | 
					
						
							|  |  |  | configuration. If you are using YAML, single backslashes are sufficient and a value | 
					
						
							|  |  |  | that's equivalent to the one shown above would be `192\.168\.\d{1,3}\.\d{1,3}`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: You can trust all proxies by setting the `internal-proxies` to empty (but don't do | 
					
						
							|  |  |  | this in production). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can take complete control of the configuration of Tomcat's `RemoteIpValve` by | 
					
						
							|  |  |  | switching the automatic one off (i.e. set `server.use-forward-headers=false`) and adding | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | a new  valve instance in a `TomcatServletWebServerFactory` bean. | 
					
						
							| 
									
										
										
										
											2015-10-02 14:57:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-configure-tomcat]] | 
					
						
							|  |  |  | === Configure Tomcat | 
					
						
							|  |  |  | Generally you can follow the advice from | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | _<<howto-discover-build-in-options-for-external-properties>>_ about | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | `@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ServletWebServerFactoryCustomizer` and various Tomcat-specific `+*Customizers+` that you | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | can add in one of those. The Tomcat APIs are quite rich so once you have access to the | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `TomcatServletWebServerFactory` you can modify it in a number of ways. Or the | 
					
						
							|  |  |  | nuclear option is to add your own `TomcatServletWebServerFactory`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-20 11:11:46 +08:00
										 |  |  | [[howto-enable-multiple-connectors-in-tomcat]] | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | === Enable Multiple Connectors with Tomcat | 
					
						
							| 
									
										
										
										
											2014-03-20 11:11:46 +08:00
										 |  |  | Add a `org.apache.catalina.connector.Connector` to the | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `TomcatServletWebServerFactory` which can allow multiple connectors, e.g. HTTP and | 
					
						
							| 
									
										
										
										
											2014-03-20 11:11:46 +08:00
										 |  |  | HTTPS connector: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | 	public ServletWebServerFactory servletContainer() { | 
					
						
							|  |  |  | 		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); | 
					
						
							| 
									
										
										
										
											2014-03-20 11:11:46 +08:00
										 |  |  | 		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); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:24:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 11:18:49 +08:00
										 |  |  | [[howto-use-tomcat-legacycookieprocessor]] | 
					
						
							|  |  |  | === Use Tomcat's LegacyCookieProcessor | 
					
						
							|  |  |  | The embedded Tomcat used by Spring Boot does not support "Version 0" of the Cookie | 
					
						
							|  |  |  | format out of the box, and you may see the following error: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If at all possible, you should consider updating your code to only store values | 
					
						
							|  |  |  | compliant with later Cookie specifications. If, however, you're unable to change the | 
					
						
							|  |  |  | way that cookies are written, you can instead configure Tomcat to use a | 
					
						
							| 
									
										
										
										
											2016-09-15 21:53:14 +08:00
										 |  |  | `LegacyCookieProcessor`. To switch to the `LegacyCookieProcessor` use an | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ServletWebServerFactoryCustomizer` bean that adds a `TomcatContextCustomizer`: | 
					
						
							| 
									
										
										
										
											2016-09-15 11:18:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 21:53:14 +08:00
										 |  |  | [source,java,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/context/embedded/TomcatLegacyCookieProcessorExample.java[tag=customizer] | 
					
						
							| 
									
										
										
										
											2016-09-15 11:18:49 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | Jetty one instead. Spring Boot provides Tomcat and Jetty dependencies bundled together | 
					
						
							|  |  |  | as separate starters to help make this process as easy as possible. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 		compile.exclude module: 'spring-boot-starter-tomcat' | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dependencies { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 		compile 'org.springframework.boot:spring-boot-starter-web' | 
					
						
							|  |  |  | 		compile 'org.springframework.boot:spring-boot-starter-jetty' | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-configure-jetty]] | 
					
						
							|  |  |  | === Configure Jetty | 
					
						
							|  |  |  | Generally you can follow the advice from | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | _<<howto-discover-build-in-options-for-external-properties>>_ about | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | `@ConfigurationProperties` (`ServerProperties` is the main one here), but also look at | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ServletWebServerFactoryCustomizer`. The Jetty APIs are quite rich so once you have | 
					
						
							|  |  |  | access to the `JettyServletWebServerFactory` you can modify it in a number | 
					
						
							|  |  |  | of ways. Or the nuclear option is to add your own `JettyServletWebServerFactory`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | [[howto-use-undertow-instead-of-tomcat]] | 
					
						
							|  |  |  | === Use Undertow instead of Tomcat | 
					
						
							|  |  |  | Using Undertow instead of Tomcat is very similar to <<howto-use-jetty-instead-of-tomcat, | 
					
						
							|  |  |  | using Jetty instead of Tomcat>>. You need to exclude the Tomcat dependencies and include | 
					
						
							|  |  |  | the Undertow starter instead. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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-undertow</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example in Gradle: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	configurations { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 		compile.exclude module: 'spring-boot-starter-tomcat' | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dependencies { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 		compile 'org.springframework.boot:spring-boot-starter-web' | 
					
						
							|  |  |  | 		compile 'org.springframework.boot:spring-boot-starter-undertow' | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 02:04:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | [[howto-configure-undertow]] | 
					
						
							|  |  |  | === Configure Undertow | 
					
						
							|  |  |  | Generally you can follow the advice from | 
					
						
							|  |  |  | _<<howto-discover-build-in-options-for-external-properties>>_ about | 
					
						
							| 
									
										
										
										
											2014-11-26 18:55:33 +08:00
										 |  |  | `@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow` are the | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | main ones here), but also look at | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `ServletWebServerFactoryCustomizer`. Once you have access to the | 
					
						
							|  |  |  | `UndertowServletWebServerFactory` you can use an `UndertowBuilderCustomizer` to | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | modify Undertow's configuration to meet your needs. Or the nuclear option is to add your | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | own `UndertowServletWebServerFactory`. | 
					
						
							| 
									
										
										
										
											2014-11-19 05:00:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 02:04:50 +08:00
										 |  |  | [[howto-enable-multiple-listeners-in-undertow]] | 
					
						
							|  |  |  | === Enable Multiple Listeners with Undertow | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | Add an `UndertowBuilderCustomizer` to the `UndertowServletWebServerFactory` and | 
					
						
							| 
									
										
										
										
											2015-01-08 02:04:50 +08:00
										 |  |  | add a listener to the `Builder`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | 	public UndertowServletWebServerFactory servletWebServerFactory() { | 
					
						
							|  |  |  | 		UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); | 
					
						
							| 
									
										
										
										
											2015-01-08 02:04:50 +08:00
										 |  |  | 		factory.addBuilderCustomizers(new UndertowBuilderCustomizer() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			@Override | 
					
						
							|  |  |  | 			public void customize(Builder builder) { | 
					
						
							|  |  |  | 				builder.addHttpListener(8080, "0.0.0.0"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		return factory; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 23:02:48 +08:00
										 |  |  | [[howto-create-websocket-endpoints-using-serverendpoint]] | 
					
						
							|  |  |  | === Create WebSocket endpoints using @ServerEndpoint | 
					
						
							|  |  |  | If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded | 
					
						
							|  |  |  | container, you must declare a single `ServerEndpointExporter` `@Bean`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							|  |  |  | 	public ServerEndpointExporter serverEndpointExporter() { | 
					
						
							|  |  |  | 		return new ServerEndpointExporter(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This bean will register any `@ServerEndpoint` annotated beans with the underlying | 
					
						
							|  |  |  | WebSocket container. When deployed to a standalone servlet container this role is | 
					
						
							|  |  |  | performed by a servlet container initializer and the `ServerEndpointExporter` bean is | 
					
						
							|  |  |  | not required. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | [[how-to-enable-http-response-compression]] | 
					
						
							|  |  |  | === Enable HTTP response compression | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  | HTTP response compression is supported by Jetty, Tomcat, and Undertow. It can be enabled | 
					
						
							|  |  |  | via `application.properties`: | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  | 	server.compression.enabled=true | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  | By default, responses must be at least 2048 bytes in length for compression to be | 
					
						
							|  |  |  | performed. This can be configured using the `server.compression.min-response-size` | 
					
						
							|  |  |  | property. | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  | By default, responses will only be compressed if their content type is one of the | 
					
						
							|  |  |  | following: | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  |  - `text/html` | 
					
						
							|  |  |  |  - `text/xml` | 
					
						
							|  |  |  |  - `text/plain` | 
					
						
							|  |  |  |  - `text/css` | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 21:50:48 +08:00
										 |  |  | This can be configured using the `server.compression.mime-types` property. | 
					
						
							| 
									
										
										
										
											2015-01-16 19:09:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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. | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | Sometimes in a browser you might see XML responses because browsers tend to send accept | 
					
						
							|  |  |  | headers that prefer XML. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-11 17:13:56 +08:00
										 |  |  | [[howto-write-an-xml-rest-service]] | 
					
						
							| 
									
										
										
										
											2014-04-11 14:07:34 +08:00
										 |  |  | === Write an XML REST service | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, it will | 
					
						
							|  |  |  | be used to render XML responses and the very same example as we used for JSON would work. | 
					
						
							|  |  |  | To use it, add the following dependency to your project: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>com.fasterxml.jackson.dataformat</groupId> | 
					
						
							|  |  |  | 		<artifactId>jackson-dataformat-xml</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | You may also want to add a dependency on Woodstox. It's faster than the default StAX | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | implementation provided by the JDK and also adds pretty print support and improved | 
					
						
							|  |  |  | namespace handling: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.codehaus.woodstox</groupId> | 
					
						
							|  |  |  | 		<artifactId>woodstox-core-asl</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If Jackson's XML extension is not available, JAXB (provided by default in the JDK) will | 
					
						
							|  |  |  | be used, with the additional requirement to have `MyThing` annotated as | 
					
						
							|  |  |  | `@XmlRootElement`: | 
					
						
							| 
									
										
										
										
											2014-04-11 14:07:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 	@XmlRootElement | 
					
						
							| 
									
										
										
										
											2014-04-11 14:07:34 +08:00
										 |  |  | 	public class MyThing { | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | 		private String name; | 
					
						
							|  |  |  | 		// .. getters and setters | 
					
						
							| 
									
										
										
										
											2014-04-11 14:07:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | To get the server to render XML instead of JSON you might have to send an | 
					
						
							|  |  |  | `Accept: text/xml` header (or use a browser). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-customize-the-jackson-objectmapper]] | 
					
						
							|  |  |  | === Customize the Jackson ObjectMapper | 
					
						
							|  |  |  | Spring MVC (client and server side) uses `HttpMessageConverters` to negotiate content | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | conversion in an HTTP exchange. If Jackson is on the classpath you already get the | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | default converter(s) provided by `Jackson2ObjectMapperBuilder`, an instance of which | 
					
						
							|  |  |  | is auto-configured for you. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | The `ObjectMapper` (or `XmlMapper` for Jackson XML converter) instance created by default | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | has the following customized properties: | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-11 08:27:26 +08:00
										 |  |  | * `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled | 
					
						
							|  |  |  | * `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` is disabled | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Spring Boot has also some features to make it easier to customize this behavior. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can configure the `ObjectMapper` and `XmlMapper` instances using the environment. | 
					
						
							|  |  |  | Jackson provides an extensive suite of simple on/off features that can be used to | 
					
						
							| 
									
										
										
										
											2015-06-15 03:51:28 +08:00
										 |  |  | configure various aspects of its processing. These features are described in six enums in | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | Jackson which map onto properties in the environment: | 
					
						
							| 
									
										
										
										
											2014-08-07 00:08:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | |=== | 
					
						
							|  |  |  | |Jackson enum|Environment property | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.databind.DeserializationFeature` | 
					
						
							|  |  |  | |`spring.jackson.deserialization.<feature_name>=true\|false` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.core.JsonGenerator.Feature` | 
					
						
							|  |  |  | |`spring.jackson.generator.<feature_name>=true\|false` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.databind.MapperFeature` | 
					
						
							|  |  |  | |`spring.jackson.mapper.<feature_name>=true\|false` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.core.JsonParser.Feature` | 
					
						
							|  |  |  | |`spring.jackson.parser.<feature_name>=true\|false` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.databind.SerializationFeature` | 
					
						
							|  |  |  | |`spring.jackson.serialization.<feature_name>=true\|false` | 
					
						
							| 
									
										
										
										
											2015-06-15 03:51:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | |`com.fasterxml.jackson.annotation.JsonInclude.Include` | 
					
						
							| 
									
										
										
										
											2016-09-21 18:38:26 +08:00
										 |  |  | |`spring.jackson.default-property-inclusion=always\|non_null\|non_absent\|non_default\|non_empty` | 
					
						
							| 
									
										
										
										
											2014-08-07 00:08:21 +08:00
										 |  |  | |=== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 16:37:02 +08:00
										 |  |  | For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`. | 
					
						
							|  |  |  | Note that, thanks to the use of <<boot-features-external-config-relaxed-binding, | 
					
						
							|  |  |  | relaxed binding>>, the case of `indent_output` doesn't have to match the case of the | 
					
						
							|  |  |  | corresponding enum constant which is `INDENT_OUTPUT`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | This environment-based configuration is applied to the auto-configured | 
					
						
							|  |  |  | `Jackson2ObjectMapperBuilder` bean, and will apply to any mappers created | 
					
						
							|  |  |  | using the builder, including the auto-configured `ObjectMapper` bean. | 
					
						
							| 
									
										
										
										
											2014-08-07 00:08:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | The context's `Jackson2ObjectMapperBuilder` can be customized by one or more | 
					
						
							|  |  |  | `Jackson2ObjectMapperBuilderCustomizer` beans. Such customizer beans can be ordered and | 
					
						
							|  |  |  | Boot's own customizer has an order of 0, allowing additional customization to be applied | 
					
						
							|  |  |  | both before and after Boot's customization. | 
					
						
							| 
									
										
										
										
											2014-08-07 00:08:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | Any beans of type `com.fasterxml.jackson.databind.Module` will be automatically registered | 
					
						
							|  |  |  | with the auto-configured `Jackson2ObjectMapperBuilder` and applied to any `ObjectMapper` | 
					
						
							|  |  |  | instances that it creates. This provides a global mechanism for contributing custom | 
					
						
							|  |  |  | modules when you add new features to your application. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | If you want to replace the default `ObjectMapper` completely, either define a `@Bean` of | 
					
						
							|  |  |  | that type and mark it as `@Primary`, or, if you prefer the builder-based | 
					
						
							| 
									
										
										
										
											2016-08-23 21:08:22 +08:00
										 |  |  | approach, define a `Jackson2ObjectMapperBuilder` `@Bean`. Note that in either case this | 
					
						
							| 
									
										
										
										
											2017-03-28 16:05:33 +08:00
										 |  |  | will disable all auto-configuration of the `ObjectMapper`. | 
					
						
							| 
									
										
										
										
											2016-08-19 04:35:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | If you provide any `@Beans` of type `MappingJackson2HttpMessageConverter` then | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | See also the _<<howto-customize-the-responsebody-rendering>>_ section and the | 
					
						
							| 
									
										
										
										
											2017-04-29 14:30:06 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | source code for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-customize-the-responsebody-rendering]] | 
					
						
							|  |  |  | === Customize the @ResponseBody rendering | 
					
						
							|  |  |  | Spring uses `HttpMessageConverters` to render `@ResponseBody` (or responses from | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | `@RestController`). You can contribute additional converters by simply adding beans of | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 14:30:06 +08:00
										 |  |  | See the {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | source code for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-22 03:18:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 21:41:36 +08:00
										 |  |  | [[howto-multipart-file-upload-configuration]] | 
					
						
							|  |  |  | === Handling Multipart File Uploads | 
					
						
							|  |  |  | Spring Boot embraces the Servlet 3 `javax.servlet.http.Part` API to support uploading | 
					
						
							| 
									
										
										
										
											2016-11-30 09:19:20 +08:00
										 |  |  | files. By default Spring Boot configures Spring MVC with a maximum file of 1MB per | 
					
						
							|  |  |  | file and a maximum of 10MB of file data in a single request. You may override these | 
					
						
							| 
									
										
										
										
											2014-04-25 21:41:36 +08:00
										 |  |  | values, as well as the location to which intermediate data is stored (e.g., to the `/tmp` | 
					
						
							|  |  |  | directory) and the threshold past which data is flushed to disk by using the properties | 
					
						
							|  |  |  | exposed in the `MultipartProperties` class. If you want to specify that files be | 
					
						
							| 
									
										
										
										
											2017-05-03 22:02:30 +08:00
										 |  |  | unlimited, for example, set the `spring.servlet.multipart.max-file-size` property to `-1`. | 
					
						
							| 
									
										
										
										
											2014-04-25 21:41:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The multipart support is helpful when you want to receive multipart encoded file data as | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | a `@RequestParam`-annotated parameter of type `MultipartFile` in a Spring MVC controller | 
					
						
							| 
									
										
										
										
											2014-04-25 21:41:36 +08:00
										 |  |  | handler method. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 14:30:06 +08:00
										 |  |  | See the {sc-spring-boot-autoconfigure}/web/servlet/MultipartAutoConfiguration.{sc-ext}[`MultipartAutoConfiguration`] | 
					
						
							| 
									
										
										
										
											2014-10-03 11:45:05 +08:00
										 |  |  | source for more details. | 
					
						
							| 
									
										
										
										
											2014-04-22 03:18:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  | [[howto-customize-view-resolvers]] | 
					
						
							|  |  |  | === Customize ViewResolvers | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | A `ViewResolver` is a core component of Spring MVC, translating view names in | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | `@Controller` to actual `View` implementations. Note that `ViewResolvers` are mainly | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  | 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: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | * An `InternalResourceViewResolver` with bean id '`defaultViewResolver`'. This one locates | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2015-06-18 19:55:44 +08:00
										 |  |  |   `spring.mvc.view.prefix` and `spring.mvc.view.suffix`). It can be overridden by providing a | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   bean of the same type. | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | * A `BeanNameViewResolver` with id '`beanNameViewResolver`'. This is a useful member of the | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   view resolver chain and will pick up any beans with the same name as the `View` being | 
					
						
							| 
									
										
										
										
											2014-06-17 17:39:11 +08:00
										 |  |  |   resolved. It shouldn't be necessary to override or replace it. | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | * 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 | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   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. | 
					
						
							| 
									
										
										
										
											2014-03-22 22:44:30 +08:00
										 |  |  |   You can switch off the auto-configured | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   `ContentNegotiatingViewResolver` by defining a bean named '`viewResolver`'. | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  | * If you use Thymeleaf you will also have a `ThymeleafViewResolver` with id | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   '`thymeleafViewResolver`'. It looks for resources by surrounding the view name with a | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   prefix and suffix (externalized to `spring.thymeleaf.prefix` and | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   `spring.thymeleaf.suffix`, defaults '`classpath:/templates/`' and '`.html`' | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  |   respectively). It can be overridden by providing a bean of the same name. | 
					
						
							| 
									
										
										
										
											2014-04-30 00:46:55 +08:00
										 |  |  | * If you use FreeMarker you will also have a `FreeMarkerViewResolver` with id | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   '`freeMarkerViewResolver`'. It looks for resources in a loader path (externalized to | 
					
						
							|  |  |  |   `spring.freemarker.templateLoaderPath`, default '`classpath:/templates/`') by | 
					
						
							| 
									
										
										
										
											2014-04-30 00:46:55 +08:00
										 |  |  |   surrounding the view name with a prefix and suffix (externalized to `spring.freemarker.prefix` | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   and `spring.freemarker.suffix`, with empty and '`.ftl`' defaults respectively). It can | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  |   be overridden by providing a bean of the same name. | 
					
						
							| 
									
										
										
										
											2014-05-08 00:34:24 +08:00
										 |  |  | * If you use Groovy templates (actually if groovy-templates is on your classpath) you will | 
					
						
							| 
									
										
										
										
											2015-04-19 19:47:53 +08:00
										 |  |  |   also have a `GroovyMarkupViewResolver` with id '`groovyMarkupViewResolver`'. It | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  |   looks for resources in a loader path by surrounding the view name with a prefix and | 
					
						
							|  |  |  |   suffix (externalized to `spring.groovy.template.prefix` and | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  |   `spring.groovy.template.suffix`, defaults '`classpath:/templates/`' and '`.tpl`' | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  |   respectively). It can be overridden by providing a bean of the same name. | 
					
						
							| 
									
										
										
										
											2014-05-16 22:28:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 14:30:06 +08:00
										 |  |  | Check out {sc-spring-boot-autoconfigure}/web/servlet/WebMvcAutoConfiguration.{sc-ext}[`WebMvcAutoConfiguration`], | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`], | 
					
						
							| 
									
										
										
										
											2016-09-29 21:05:49 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`] and | 
					
						
							|  |  |  | {sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`] | 
					
						
							| 
									
										
										
										
											2015-08-19 20:32:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-15 06:53:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-03 11:17:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-07 17:56:33 +08:00
										 |  |  | [[howto-http-clients]] | 
					
						
							|  |  |  | == HTTP clients | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-http-clients-proxy-configuration]] | 
					
						
							|  |  |  | === Configure RestTemplate to use a proxy | 
					
						
							|  |  |  | As described in <<spring-boot-features.adoc#boot-features-restclient-customization>>, | 
					
						
							|  |  |  | a `RestTemplateCustomizer` can be used with `RestTemplateBuilder` to build a customized | 
					
						
							|  |  |  | `RestTemplate`. This is the recommended approach for creating a `RestTemplate` configured | 
					
						
							|  |  |  | to use a proxy. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The exact details of the proxy configuration depend on the underlying client request | 
					
						
							|  |  |  | factory that is being used. Here's an example of configuring | 
					
						
							|  |  |  | `HttpComponentsClientRequestFactory` with an `HttpClient` that uses a proxy for all hosts | 
					
						
							|  |  |  | except `192.168.0.5`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/web/client/RestTemplateProxyCustomizationExample.java[tag=customizer] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-logging]] | 
					
						
							|  |  |  | == Logging | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 21:43:47 +08:00
										 |  |  | Spring Boot has no mandatory logging dependency, except for the Commons Logging API, of | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | which there are many implementations to choose from. To use http://logback.qos.ch[Logback] | 
					
						
							| 
									
										
										
										
											2016-05-24 21:43:47 +08:00
										 |  |  | you need to include it and `jcl-over-slf4j` (which implements the Commons Logging API) on | 
					
						
							|  |  |  | the classpath. The simplest way to do that is through the starters which all depend on | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | `spring-boot-starter-logging`. For a web application you only need | 
					
						
							| 
									
										
										
										
											2016-05-24 21:43:47 +08:00
										 |  |  | `spring-boot-starter-web` since it depends transitively on the logging starter. For | 
					
						
							|  |  |  | example, using Maven: | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 		<artifactId>spring-boot-starter-web</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 02:26:15 +08:00
										 |  |  | Spring Boot has a `LoggingSystem` abstraction that attempts to configure logging based on | 
					
						
							| 
									
										
										
										
											2014-06-27 21:56:39 +08:00
										 |  |  | the content of the classpath. If Logback is available it is the first choice. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the only change you need to make to logging is to set the levels of various loggers | 
					
						
							|  |  |  | then you can do that in `application.properties` using the "logging.level" prefix, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-06-14 15:36:10 +08:00
										 |  |  | 	logging.level.org.springframework.web=DEBUG | 
					
						
							|  |  |  | 	logging.level.org.hibernate=ERROR | 
					
						
							| 
									
										
										
										
											2014-06-27 21:56:39 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can also set the location of a file to log to (in addition to the console) using | 
					
						
							| 
									
										
										
										
											2014-07-03 06:52:46 +08:00
										 |  |  | "logging.file". | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | To configure the more fine-grained settings of a logging system you need to use the native | 
					
						
							| 
									
										
										
										
											2014-07-03 06:52:46 +08:00
										 |  |  | configuration format supported by the `LoggingSystem` in question. By default Spring Boot | 
					
						
							|  |  |  | picks up the native configuration from its default location for the system (e.g. | 
					
						
							| 
									
										
										
										
											2014-07-21 18:39:43 +08:00
										 |  |  | `classpath:logback.xml` for Logback), but you can set the location of the config file | 
					
						
							| 
									
										
										
										
											2014-07-03 06:52:46 +08:00
										 |  |  | using the "logging.config" property. | 
					
						
							| 
									
										
										
										
											2014-06-27 21:56:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | [[howto-configure-logback-for-logging]] | 
					
						
							| 
									
										
										
										
											2014-06-27 21:56:39 +08:00
										 |  |  | === Configure Logback for logging | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  | If you put a `logback.xml` in the root of your classpath it will be picked up from | 
					
						
							| 
									
										
										
										
											2015-08-17 23:45:44 +08:00
										 |  |  | there | 
					
						
							| 
									
										
										
										
											2015-12-17 06:24:03 +08:00
										 |  |  | (or `logback-spring.xml` to take advantage of the templating features provided by Boot). | 
					
						
							|  |  |  | Spring Boot provides a default base configuration that you can include if you just | 
					
						
							| 
									
										
										
										
											2015-06-27 06:33:33 +08:00
										 |  |  | want to set levels, e.g. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [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> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-10 18:50:17 +08:00
										 |  |  | If you look at that `base.xml` in the spring-boot jar, you will see that it uses | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | * `${LOG_PATH}` if `logging.path` was set (representing a directory for | 
					
						
							| 
									
										
										
										
											2015-08-06 18:34:45 +08:00
										 |  |  |    log files to live in). | 
					
						
							|  |  |  | * `${LOG_EXCEPTION_CONVERSION_WORD}` if `logging.exception-conversion-word` was set in | 
					
						
							|  |  |  |    Boot's external configuration. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 06:24:03 +08:00
										 |  |  | [[howto-configure-logback-for-logging-fileonly]] | 
					
						
							|  |  |  | ==== Configure logback for file only output | 
					
						
							|  |  |  | If you want to disable console logging and write output only to a file you need a custom | 
					
						
							| 
									
										
										
										
											2016-01-21 16:52:08 +08:00
										 |  |  | `logback-spring.xml` that imports `file-appender.xml` but not `console-appender.xml`: | 
					
						
							| 
									
										
										
										
											2015-12-17 06:24:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<?xml version="1.0" encoding="UTF-8"?> | 
					
						
							|  |  |  | 	<configuration> | 
					
						
							|  |  |  | 		<include resource="org/springframework/boot/logging/logback/defaults.xml" /> | 
					
						
							|  |  |  | 		<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/> | 
					
						
							|  |  |  | 		<include resource="org/springframework/boot/logging/logback/file-appender.xml" /> | 
					
						
							|  |  |  | 		<root level="INFO"> | 
					
						
							|  |  |  | 			<appender-ref ref="FILE" /> | 
					
						
							|  |  |  | 		</root> | 
					
						
							|  |  |  | 	</configuration> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You also need to add `logging.file` to your `application.properties`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	logging.file=myapplication.log | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-configure-log4j-for-logging]] | 
					
						
							|  |  |  | === Configure Log4j for logging | 
					
						
							| 
									
										
										
										
											2016-01-25 20:43:36 +08:00
										 |  |  | Spring Boot supports http://logging.apache.org/log4j/2.x[Log4j 2] for logging | 
					
						
							| 
									
										
										
										
											2016-05-18 14:55:42 +08:00
										 |  |  | configuration if it is on the classpath. If you are using the starters for | 
					
						
							| 
									
										
										
										
											2016-01-25 20:43:36 +08:00
										 |  |  | assembling dependencies that means you have to exclude Logback and then include log4j 2 | 
					
						
							| 
									
										
										
										
											2016-05-24 21:43:47 +08:00
										 |  |  | instead. If you aren't using the starters then you need to provide `jcl-over-slf4j` | 
					
						
							| 
									
										
										
										
											2016-01-25 20:43:36 +08:00
										 |  |  | (at least) in addition to Log4j 2. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 14:55:42 +08:00
										 |  |  | The simplest path is probably through the starters, even though it requires some | 
					
						
							| 
									
										
										
										
											2014-09-16 01:24:46 +08:00
										 |  |  | jiggling with excludes, .e.g. in Maven: | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 		<artifactId>spring-boot-starter-web</artifactId> | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 	</dependency> | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 		<artifactId>spring-boot-starter</artifactId> | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 		<exclusions> | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | 			<exclusion> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-starter-logging</artifactId> | 
					
						
							|  |  |  | 			</exclusion> | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 		</exclusions> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							| 
									
										
										
										
											2016-01-25 20:43:36 +08:00
										 |  |  | 		<artifactId>spring-boot-starter-log4j2</artifactId> | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 	</dependency> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-25 20:43:36 +08:00
										 |  |  | NOTE: The use of the Log4j starters gathers together the dependencies for common logging | 
					
						
							|  |  |  | requirements (e.g. including having Tomcat use `java.util.logging` but configuring the | 
					
						
							|  |  |  | output using Log4j 2). See the Actuator Log4j 2 samples for more detail and to see it in | 
					
						
							|  |  |  | action. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 23:06:20 +08:00
										 |  |  | [[howto-configure-log4j-for-logging-yaml-or-json-config]] | 
					
						
							|  |  |  | ==== Use YAML or JSON to configure Log4j 2 | 
					
						
							|  |  |  | In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON | 
					
						
							| 
									
										
										
										
											2016-01-15 20:51:19 +08:00
										 |  |  | configuration files. To configure Log4j 2 to use an alternative configuration file format, | 
					
						
							|  |  |  | add the appropriate dependencies to the classpath and name your | 
					
						
							|  |  |  | configuration files to match your chosen file format: | 
					
						
							| 
									
										
										
										
											2015-01-22 23:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-15 20:51:19 +08:00
										 |  |  | [cols="10,75,15"] | 
					
						
							|  |  |  | |=== | 
					
						
							|  |  |  | |Format|Dependencies|File names | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |YAML | 
					
						
							|  |  |  | a| `com.fasterxml.jackson.core:jackson-databind` + | 
					
						
							|  |  |  |    `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` | 
					
						
							|  |  |  | a| `log4j2.yaml` + | 
					
						
							|  |  |  |    `log4j2.yml` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | |JSON | 
					
						
							|  |  |  | a| `com.fasterxml.jackson.core:jackson-databind` | 
					
						
							|  |  |  | a| `log4j2.json` + | 
					
						
							|  |  |  |    `log4j2.jsn` | 
					
						
							|  |  |  | |=== | 
					
						
							| 
									
										
										
										
											2015-01-22 23:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-data-access]] | 
					
						
							|  |  |  | == Data Access | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-configure-a-datasource]] | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | === Configure a custom DataSource | 
					
						
							|  |  |  | To configure your own `DataSource` define a `@Bean` of that type in your configuration. | 
					
						
							|  |  |  | Spring Boot will reuse your `DataSource` anywhere one is required, including database | 
					
						
							|  |  |  | initialization. If you need to externalize some settings, you can easily bind your | 
					
						
							|  |  |  | `DataSource` to the environment (see | 
					
						
							|  |  |  | <<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>>). | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 	@ConfigurationProperties(prefix="app.datasource") | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 	public DataSource dataSource() { | 
					
						
							|  |  |  | 		return new FancyDataSource(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 	app.datasource.url=jdbc:h2:mem:mydb | 
					
						
							|  |  |  | 	app.datasource.username=sa | 
					
						
							|  |  |  | 	app.datasource.pool-size=30 | 
					
						
							| 
									
										
										
										
											2016-08-22 17:49:32 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | Assuming that your `FancyDataSource` has regular JavaBean properties for the url, the | 
					
						
							|  |  |  | username and the pool size, these settings will be bound automatically before the | 
					
						
							|  |  |  | `DataSource` is made available to other components. The regular | 
					
						
							|  |  |  | <<howto-initialize-a-database-using-spring-jdbc,database initialization>> will also happen | 
					
						
							|  |  |  | (so the relevant sub-set of `spring.datasource.*` can still be used with your custom | 
					
						
							|  |  |  | configuration). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can apply the same principle if you are configuring a custom JNDI `DataSource`: | 
					
						
							| 
									
										
										
										
											2016-08-22 17:49:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 	@Bean(destroyMethod="") | 
					
						
							|  |  |  | 	@ConfigurationProperties(prefix="app.datasource") | 
					
						
							|  |  |  | 	public DataSource dataSource() throws Exception { | 
					
						
							|  |  |  | 		JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); | 
					
						
							|  |  |  | 		return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS"); | 
					
						
							| 
									
										
										
										
											2016-08-22 17:49:32 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-26 08:45:59 +08:00
										 |  |  | Spring Boot also provides a utility builder class `DataSourceBuilder` that can be used to | 
					
						
							|  |  |  | create one of the standard data sources (if it is on the classpath). The builder can | 
					
						
							|  |  |  | detect the one to use based on what's available on the classpath. It also auto detects the | 
					
						
							|  |  |  | driver based on the JDBC url. | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To run an app with that `DataSource`, all that is needed really is the connection | 
					
						
							|  |  |  | information; pool-specific settings can also be provided, check the implementation that | 
					
						
							|  |  |  | is going to be used at runtime for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	app.datasource.url=jdbc:mysql://localhost/test | 
					
						
							|  |  |  | 	app.datasource.username=dbuser | 
					
						
							|  |  |  | 	app.datasource.password=dbpass | 
					
						
							|  |  |  | 	app.datasource.pool-size=30 | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There is a catch however. Because the actual type of the connection pool is not exposed, | 
					
						
							|  |  |  | no keys are generated in the metadata for your custom `DataSource` and no completion is | 
					
						
							|  |  |  | available in your IDE (The `DataSource` interface doesn't expose any property). Also, if | 
					
						
							| 
									
										
										
										
											2017-05-15 05:35:08 +08:00
										 |  |  | you happen to have Hikari on the classpath, this basic setup will not work because Hikari | 
					
						
							|  |  |  | has no `url` parameter (but a `jdbcUrl` parameter). You will have to rewrite your | 
					
						
							|  |  |  | configuration as follows: | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 17:49:32 +08:00
										 |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 	app.datasource.jdbc-url=jdbc:mysql://localhost/test | 
					
						
							|  |  |  | 	app.datasource.username=dbuser | 
					
						
							|  |  |  | 	app.datasource.password=dbpass | 
					
						
							|  |  |  | 	app.datasource.maximum-pool-size=30 | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can fix that by forcing the connection pool to use and return a dedicated | 
					
						
							|  |  |  | implementation rather than `DataSource`. You won't be able to change the implementation | 
					
						
							|  |  |  | at runtime but the list of options will be explicit. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can even go further by leveraging what `DataSourceProperties` does for you, that is | 
					
						
							|  |  |  | providing a default embedded database if no url is provided with a sensible username and | 
					
						
							|  |  |  | password for it. You can easily initialize a `DataSourceBuilder` from the state of any | 
					
						
							|  |  |  | `DataSourceProperties` so you could just as well inject the one Spring Boot creates | 
					
						
							|  |  |  | automatically. However, that would split your configuration in two namespaces: url, | 
					
						
							|  |  |  | username, password, type and driver on `spring.datasource` and the rest on your custom | 
					
						
							|  |  |  | namespace (`app.datasource`). To avoid that, you can redefine a custom | 
					
						
							|  |  |  | `DataSourceProperties` on your custom namespace: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration] | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | This setup puts you _in pair_ with what Spring Boot does for you by default, except that | 
					
						
							|  |  |  | a dedicated connection pool is chosen (in code) and its settings are exposed in the same | 
					
						
							|  |  |  | namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl` | 
					
						
							|  |  |  | translation for you, you can configure it like this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	app.datasource.url=jdbc:mysql://localhost/test | 
					
						
							|  |  |  | 	app.datasource.username=dbuser | 
					
						
							|  |  |  | 	app.datasource.password=dbpass | 
					
						
							|  |  |  | 	app.datasource.maximum-pool-size=30 | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type` | 
					
						
							|  |  |  | will have no effect. In practice the builder will be initialized with whatever value you | 
					
						
							| 
									
										
										
										
											2017-03-28 16:05:33 +08:00
										 |  |  | might set there and then overridden by the call to `.type()`. | 
					
						
							| 
									
										
										
										
											2016-08-22 17:49:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | See _<<spring-boot-features.adoc#boot-features-configure-datasource>>_ in the | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | '`Spring Boot features`' section and the | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`] | 
					
						
							|  |  |  | class for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-two-datasources]] | 
					
						
							|  |  |  | === Configure Two DataSources | 
					
						
							|  |  |  | If you need to configure multiple data sources, you can apply the same tricks that are | 
					
						
							|  |  |  | described in the previous section. You must, however, mark one of the `DataSource` | 
					
						
							|  |  |  | `@Primary` as various auto-configurations down the road expect to be able to get one by | 
					
						
							|  |  |  | type. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you create your own `DataSource`, the auto-configuration will back off. In the example | 
					
						
							|  |  |  | below, we provide the _exact_ same features set than what the auto-configuration provides | 
					
						
							|  |  |  | on the primary data source: | 
					
						
							| 
									
										
										
										
											2016-03-01 18:45:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration] | 
					
						
							| 
									
										
										
										
											2016-03-01 18:45:30 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | TIP: `fooDataSourceProperties` has to be flagged `@Primary` so that the database | 
					
						
							|  |  |  | initializer feature uses your copy (should you use that). | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | Both data sources are also bound for advanced customizations. For instance you could | 
					
						
							|  |  |  | configure them as follows: | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	app.datasource.foo.type=com.zaxxer.hikari.HikariDataSource | 
					
						
							|  |  |  | 	app.datasource.foo.maximum-pool-size=30 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | 	app.datasource.bar.url=jdbc:mysql://localhost/test | 
					
						
							|  |  |  | 	app.datasource.bar.username=dbuser | 
					
						
							|  |  |  | 	app.datasource.bar.password=dbpass | 
					
						
							|  |  |  | 	app.datasource.bar.max-total=30 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | Of course, you can apply the same concept to the secondary `DataSource` as well: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration] | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-23 22:46:41 +08:00
										 |  |  | This final example configures two data sources on custom namespaces with the same logic | 
					
						
							|  |  |  | than what Spring Boot would do in auto-configuration. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-26 08:45:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-use-spring-data-repositories]] | 
					
						
							|  |  |  | === Use Spring Data repositories | 
					
						
							|  |  |  | Spring Data can create implementations for you of `@Repository` interfaces of various | 
					
						
							| 
									
										
										
										
											2014-11-07 14:43:31 +08:00
										 |  |  | flavors. Spring Boot will handle all of that for you as long as those `@Repositories` | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | `@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 | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-01-03 18:25:17 +08:00
										 |  |  | configuration properties. Some of them are automatically detected according to the context | 
					
						
							|  |  |  | so you shouldn't have to set them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `spring.jpa.hibernate.ddl-auto` is a special case in that it has different defaults | 
					
						
							|  |  |  | depending on whether you are using an embedded database (`create-drop`) or not (`none`). | 
					
						
							|  |  |  | The dialect to use is also automatically detected based on the current `DataSource` but | 
					
						
							|  |  |  | you can set `spring.jpa.database` yourself if you want to be explicit and bypass that | 
					
						
							|  |  |  | check on startup. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-14 22:16:17 +08:00
										 |  |  | NOTE: Specifying a `database` leads to the configuration of a well-defined Hibernate | 
					
						
							|  |  |  | dialect. Several databases have more than one `Dialect` and this may not suit your need. | 
					
						
							|  |  |  | In that case, you can either set `spring.jpa.database` to `default` to let Hibernate figure | 
					
						
							|  |  |  | things out or set the dialect using the `spring.jpa.database-platform` property. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 18:25:17 +08:00
										 |  |  | The most common options to set are: | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2016-04-08 20:13:23 +08:00
										 |  |  | 	spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy | 
					
						
							|  |  |  | 	spring.jpa.show-sql=true | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 18:25:17 +08:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-16 04:34:12 +08:00
										 |  |  | Hibernate defines `Physical` and `Implicit` naming strategies: Spring Boot configures | 
					
						
							|  |  |  | `SpringPhysicalNamingStrategy` by default. This implementation provides the same | 
					
						
							|  |  |  | table structure as Hibernate 4. If you'd rather use Hibernate 5's default instead, set | 
					
						
							|  |  |  | the following property: | 
					
						
							| 
									
										
										
										
											2016-04-15 14:54:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 00:13:40 +08:00
										 |  |  | [[howto-use-custom-entity-manager]] | 
					
						
							|  |  |  | === Use a custom EntityManagerFactory | 
					
						
							| 
									
										
										
										
											2014-04-07 12:44:20 +08:00
										 |  |  | To take full control of the configuration of the `EntityManagerFactory`, you need to add | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | entity manager based on the presence of a bean of that type. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-use-two-entity-managers]] | 
					
						
							|  |  |  | === Use Two EntityManagers | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | Even if the default `EntityManagerFactory` works fine, you will need to define a new one | 
					
						
							|  |  |  | because otherwise the presence of the second bean of that type will switch off the | 
					
						
							|  |  |  | default. To make it easy to do that you can use the convenient `EntityManagerBuilder` | 
					
						
							|  |  |  | provided by Spring Boot, or if you prefer you can just use the | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | `LocalContainerEntityManagerFactoryBean` directly from Spring ORM. | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | Example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	// add two data sources configured as above | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@Bean | 
					
						
							|  |  |  | 	public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory( | 
					
						
							|  |  |  | 			EntityManagerFactoryBuilder builder) { | 
					
						
							|  |  |  | 		return builder | 
					
						
							|  |  |  | 				.dataSource(customerDataSource()) | 
					
						
							|  |  |  | 				.packages(Customer.class) | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 				.persistenceUnit("customers") | 
					
						
							|  |  |  | 				.build(); | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-04-07 12:44:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 	@Bean | 
					
						
							|  |  |  | 	public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory( | 
					
						
							|  |  |  | 			EntityManagerFactoryBuilder builder) { | 
					
						
							|  |  |  | 		return builder | 
					
						
							|  |  |  | 				.dataSource(orderDataSource()) | 
					
						
							|  |  |  | 				.packages(Order.class) | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 				.persistenceUnit("orders") | 
					
						
							|  |  |  | 				.build(); | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-04-03 00:13:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | The configuration above almost works on its own. To complete the picture you need to | 
					
						
							|  |  |  | configure `TransactionManagers` for the two `EntityManagers` as well. One of them could | 
					
						
							|  |  |  | be picked up by the default `JpaTransactionManager` in Spring Boot if you mark it as | 
					
						
							|  |  |  | `@Primary`. The other would have to be explicitly injected into a new instance. Or you | 
					
						
							|  |  |  | might be able to use a JTA transaction manager spanning both. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-07 16:13:34 +08:00
										 |  |  | If you are using Spring Data, you need to configure `@EnableJpaRepositories` accordingly: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Configuration | 
					
						
							|  |  |  | 	@EnableJpaRepositories(basePackageClasses = Customer.class, | 
					
						
							|  |  |  | 			entityManagerFactoryRef = "customerEntityManagerFactory") | 
					
						
							|  |  |  | 	public class CustomerConfiguration { | 
					
						
							|  |  |  | 		... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@Configuration | 
					
						
							|  |  |  | 	@EnableJpaRepositories(basePackageClasses = Order.class, | 
					
						
							|  |  |  | 			entityManagerFactoryRef = "orderEntityManagerFactory") | 
					
						
							|  |  |  | 	public class OrderConfiguration { | 
					
						
							|  |  |  | 		... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-03 11:17:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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` | 
					
						
							| 
									
										
										
										
											2014-04-03 00:13:40 +08:00
										 |  |  | then you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | id '`entityManagerFactory`', and set the persistence unit name there. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 02:28:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-09 16:36:00 +08:00
										 |  |  | [[howto-use-spring-data-jpa--and-mongo-repositories]] | 
					
						
							| 
									
										
										
										
											2014-06-10 02:28:25 +08:00
										 |  |  | === Use Spring Data JPA and Mongo repositories | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Spring Data JPA and Spring Data Mongo can both create `Repository` implementations for you | 
					
						
							|  |  |  | automatically. If they are both present on the classpath, you might have to do some extra | 
					
						
							|  |  |  | configuration to tell Spring Boot which one (or both) you want to create repositories for | 
					
						
							|  |  |  | you. The most explicit way to do that is to use the standard Spring Data | 
					
						
							| 
									
										
										
										
											2014-10-10 03:40:34 +08:00
										 |  |  | `+@Enable*Repositories+` and tell it the location of your `Repository` interfaces | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | (where '`*`' is '`Jpa`' or '`Mongo`' or both). | 
					
						
							| 
									
										
										
										
											2014-06-10 02:28:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 03:40:34 +08:00
										 |  |  | There are also flags `+spring.data.*.repositories.enabled+` that you can use to switch the | 
					
						
							| 
									
										
										
										
											2014-06-10 02:28:25 +08:00
										 |  |  | auto-configured repositories on and off in external configuration.  This is useful for | 
					
						
							|  |  |  | instance in case you want to switch off the Mongo repositories and still use the | 
					
						
							|  |  |  | auto-configured `MongoTemplate`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The same obstacle and the same features exist for other auto-configured Spring Data | 
					
						
							|  |  |  | repository types (Elasticsearch, Solr). Just change the names of the annotations and flags | 
					
						
							|  |  |  | respectively. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-24 11:21:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-10 23:00:11 +08:00
										 |  |  | [[howto-use-exposing-spring-data-repositories-rest-endpoint]] | 
					
						
							|  |  |  | === Expose Spring Data repositories as REST endpoint | 
					
						
							|  |  |  | Spring Data REST can expose the `Repository` implementations as REST endpoints for you as | 
					
						
							|  |  |  | long as Spring MVC has been enabled for the application. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Spring Boot exposes as set of useful properties from the `spring.data.rest` namespace that | 
					
						
							| 
									
										
										
										
											2015-07-21 23:27:24 +08:00
										 |  |  | customize the | 
					
						
							|  |  |  | {spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`]. | 
					
						
							|  |  |  | If you need to provide additional customization, you should use a | 
					
						
							| 
									
										
										
										
											2015-10-22 20:11:30 +08:00
										 |  |  | {spring-data-rest-javadoc}/webmvc/config/RepositoryRestConfigurer.{dc-ext}[`RepositoryRestConfigurer`] | 
					
						
							| 
									
										
										
										
											2015-07-21 23:27:24 +08:00
										 |  |  | bean. | 
					
						
							| 
									
										
										
										
											2015-02-10 23:00:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 17:41:44 +08:00
										 |  |  | NOTE: If you don't specify any order on your custom `RepositoryRestConfigurer` it will run | 
					
						
							|  |  |  | after the one Spring Boot uses internally. If you need to specify an order, make sure it | 
					
						
							|  |  |  | is higher than 0. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-24 11:21:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 19:19:24 +08:00
										 |  |  | [[howto-configure-a-component-that-is-used-by-JPA]] | 
					
						
							|  |  |  | === Configure a component that is used by JPA | 
					
						
							|  |  |  | If you want to configure a component that will be used by JPA then you need to ensure | 
					
						
							|  |  |  | that the component is initialized before JPA. Where the component is auto-configured | 
					
						
							|  |  |  | Spring Boot will take care of this for you. For example, when Flyway is auto-configured, | 
					
						
							|  |  |  | Hibernate is configured to depend upon Flyway so that the latter has a chance to | 
					
						
							|  |  |  | initialize the database before Hibernate tries to use it. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you are configuring a component yourself, you can use an | 
					
						
							|  |  |  | `EntityManagerFactoryDependsOnPostProcessor` subclass as a convenient way of setting up | 
					
						
							|  |  |  | the necessary dependencies. For example, if you are using Hibernate Search with | 
					
						
							|  |  |  | Elasticsearch as its index manager then any `EntityManagerFactory` beans must be | 
					
						
							|  |  |  | configured to depend on the `elasticsearchClient` bean: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | include::{code-examples}/elasticsearch/HibernateSearchElasticsearchExample.java[tag=configuration] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-database-initialization]] | 
					
						
							|  |  |  | == Database initialization | 
					
						
							|  |  |  | An SQL database can be initialized in different ways depending on what your stack is. Or | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | of course you can do it manually as long as the database is a separate process. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2015-03-14 00:30:05 +08:00
										 |  |  | values are `none`, `validate`, `update`, `create`, `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. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-28 15:45:06 +08:00
										 |  |  | NOTE: You can output the schema creation by enabling the `org.hibernate.SQL` logger. This | 
					
						
							|  |  |  | is done for you automatically if you enable the <<boot-features-logging-console-output,debug mode>>. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | In addition, a file named `import.sql` in the root of the classpath will be executed on | 
					
						
							| 
									
										
										
										
											2016-10-11 14:30:18 +08:00
										 |  |  | startup if Hibernate creates the schema from scratch (that is if the `ddl-auto` property | 
					
						
							|  |  |  | is set to `create` or `create-drop`). 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). | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-12 21:33:29 +08:00
										 |  |  | [[howto-initialize-a-database-using-spring-jdbc]] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | === 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 | 
					
						
							| 
									
										
										
										
											2014-05-10 22:26:50 +08:00
										 |  |  | classpath). In addition Spring Boot will load the `schema-${platform}.sql` | 
					
						
							|  |  |  | and `data-${platform}.sql` files (if present), where | 
					
						
							| 
									
										
										
										
											2014-04-23 16:42:10 +08:00
										 |  |  | `platform` is the value of `spring.datasource.platform`, e.g. you might choose to set | 
					
						
							| 
									
										
										
										
											2014-04-19 01:44:10 +08:00
										 |  |  | it to the vendor name of the database (`hsqldb`, `h2`, `oracle`, `mysql`, | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | `postgresql` etc.). Spring Boot enables the fail-fast feature of the Spring JDBC | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | initializer by default, so if the scripts cause exceptions the application will fail | 
					
						
							| 
									
										
										
										
											2014-06-06 21:55:10 +08:00
										 |  |  | to start. The script locations can be changed by setting `spring.datasource.schema` and | 
					
						
							|  |  |  | `spring.datasource.data`, and neither location will be processed if | 
					
						
							|  |  |  | `spring.datasource.initialize=false`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-28 23:02:15 +08:00
										 |  |  | To disable the fail-fast you can set `spring.datasource.continue-on-error=true`. This can be | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | useful once an application has matured and been deployed a few times, since the scripts | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | can act as '`poor man's migrations`' -- inserts that fail mean that the data is already | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | there, so there would be no need to prevent the application from running, for instance. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 13:48:38 +08:00
										 |  |  | If you want to use the `schema.sql` initialization in a JPA app (with | 
					
						
							|  |  |  | Hibernate) then `ddl-auto=create-drop` will lead to errors if | 
					
						
							|  |  |  | Hibernate tries to create the same tables.  To avoid those errors set | 
					
						
							|  |  |  | `ddl-auto` explicitly to "" (preferable) or "none". Whether or not you use | 
					
						
							|  |  |  | `ddl-auto=create-drop` you can always use `data.sql` to initialize new | 
					
						
							|  |  |  | data. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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]] | 
					
						
							| 
									
										
										
										
											2016-04-21 17:20:28 +08:00
										 |  |  | === Use a higher-level database migration tool | 
					
						
							|  |  |  | Spring Boot supports two higher-level migration tools: http://flywaydb.org/[Flyway] | 
					
						
							|  |  |  | and http://www.liquibase.org/[Liquibase]. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-02 02:37:25 +08:00
										 |  |  | [[howto-execute-flyway-database-migrations-on-startup]] | 
					
						
							|  |  |  | ==== Execute Flyway database migrations on startup | 
					
						
							|  |  |  | To automatically run Flyway database migrations on startup, add the | 
					
						
							| 
									
										
										
										
											2014-05-14 20:41:55 +08:00
										 |  |  | `org.flywaydb:flyway-core` to your classpath. | 
					
						
							| 
									
										
										
										
											2014-05-02 02:37:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 07:28:30 +08:00
										 |  |  | The migrations are scripts in the form `V<VERSION>__<NAME>.sql` (with `<VERSION>` an | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | underscore-separated version, e.g. '`1`' or '`2_1`'). By default they live in a folder | 
					
						
							| 
									
										
										
										
											2016-12-22 22:39:31 +08:00
										 |  |  | `classpath:db/migration` but you can modify that using `flyway.locations`. You can also | 
					
						
							|  |  |  | add a special `{vendor}` placeholder to use vendor-specific scripts. Assume the following: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,properties,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	flyway.locations=db/migration/{vendor} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rather than using `db/migration`, this configuration will set the folder to use according | 
					
						
							| 
									
										
										
										
											2017-01-04 12:43:01 +08:00
										 |  |  | to the type of the database (i.e. `db/migration/mysql` for MySQL). The list of supported | 
					
						
							| 
									
										
										
										
											2016-12-22 22:39:31 +08:00
										 |  |  | database are available in {sc-spring-boot}/jdbc/DatabaseDriver.{sc-ext}[`DatabaseDriver`]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See also the Flyway class from flyway-core for details of available settings like schemas | 
					
						
							|  |  |  | etc. In addition Spring Boot provides a small set of properties in | 
					
						
							| 
									
										
										
										
											2014-05-02 02:37:25 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`] | 
					
						
							| 
									
										
										
										
											2016-04-12 00:30:24 +08:00
										 |  |  | that can be used to disable the migrations, or switch off the location checking. Spring | 
					
						
							|  |  |  | Boot will call `Flyway.migrate()` to perform the database migration. If you would like | 
					
						
							|  |  |  | more control, provide a `@Bean` that implements | 
					
						
							|  |  |  | {sc-spring-boot-autoconfigure}/flyway/FlywayMigrationStrategy.{sc-ext}[`FlywayMigrationStrategy`]. | 
					
						
							| 
									
										
										
										
											2014-05-02 02:37:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 18:48:36 +08:00
										 |  |  | Flyway supports SQL and Java http://flywaydb.org/documentation/callbacks.html[callbacks]. | 
					
						
							|  |  |  | To use SQL-based callbacks, place the callback scripts in the `classpath:db/migration` | 
					
						
							|  |  |  | folder. To use Java-based callbacks, create one or more beans that implement | 
					
						
							|  |  |  | `FlywayCallback` or, preferably, extend `BaseFlywayCallback`. Any such beans will be | 
					
						
							|  |  |  | automatically registered with `Flyway`. They can be ordered using `@Order` or by | 
					
						
							|  |  |  | implementing `Ordered`. | 
					
						
							| 
									
										
										
										
											2016-01-15 02:33:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-26 15:55:28 +08:00
										 |  |  | By default Flyway will autowire the (`@Primary`) `DataSource` in your context and | 
					
						
							|  |  |  | use that for migrations. If you like to use a different `DataSource` you can create | 
					
						
							|  |  |  | one and mark its `@Bean` as `@FlywayDataSource` - if you do that remember to create | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | another one and mark it as `@Primary` if you want two data sources. | 
					
						
							| 
									
										
										
										
											2014-05-27 04:48:19 +08:00
										 |  |  | Or you can use Flyway's native `DataSource` by setting `flyway.[url,user,password]` | 
					
						
							| 
									
										
										
										
											2014-05-26 15:55:28 +08:00
										 |  |  | in external properties. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-02 02:37:25 +08:00
										 |  |  | There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so | 
					
						
							|  |  |  | you can see how to set things up. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-20 23:44:42 +08:00
										 |  |  | You can also use Flyway to provide data for specific scenarios. For example, you can | 
					
						
							|  |  |  | place test-specific migrations in `src/test/resources` and they will only be run when your | 
					
						
							|  |  |  | application starts for testing. If you want to be more sophisticated you can use | 
					
						
							|  |  |  | profile-specific configuration to customize `flyway.locations` so that certain migrations | 
					
						
							|  |  |  | will only run when a particular profile is active. For example, in | 
					
						
							|  |  |  | `application-dev.properties` you could set `flyway.locations` to | 
					
						
							| 
									
										
										
										
											2017-01-24 19:39:36 +08:00
										 |  |  | `classpath:/db/migration, classpath:/dev/db/migration` and migrations in `dev/db/migration` | 
					
						
							| 
									
										
										
										
											2017-01-20 23:44:42 +08:00
										 |  |  | will only run when the `dev` profile is active. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-02 20:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-18 05:59:36 +08:00
										 |  |  | [[howto-execute-liquibase-database-migrations-on-startup]] | 
					
						
							|  |  |  | ==== Execute Liquibase database migrations on startup | 
					
						
							|  |  |  | To automatically run Liquibase database migrations on startup, add the | 
					
						
							| 
									
										
										
										
											2014-05-14 20:41:55 +08:00
										 |  |  | `org.liquibase:liquibase-core` to your classpath. | 
					
						
							| 
									
										
										
										
											2014-04-18 05:59:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The master change log is by default read from `db/changelog/db.changelog-master.yaml` but | 
					
						
							| 
									
										
										
										
											2016-04-21 17:20:28 +08:00
										 |  |  | can be set using `liquibase.change-log`. In addition to YAML, Liquibase also supports | 
					
						
							|  |  |  | JSON, XML, and SQL change log formats. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-07 23:16:19 +08:00
										 |  |  | By default Liquibase will autowire the (`@Primary`) `DataSource` in your context and use | 
					
						
							|  |  |  | that for migrations. If you like to use a different `DataSource` you can create one and | 
					
						
							|  |  |  | mark its `@Bean` as `@LiquibaseDataSource` - if you do that remember to create another one | 
					
						
							|  |  |  | and mark it as `@Primary` if you want two data sources. Or you can use Liquibase's native | 
					
						
							|  |  |  | `DataSource` by setting `liquibase.[url,user,password]` in external properties. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 17:20:28 +08:00
										 |  |  | See | 
					
						
							| 
									
										
										
										
											2014-04-18 05:59:36 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[`LiquibaseProperties`] | 
					
						
							|  |  |  | for details of available settings like contexts, default schema etc. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-21 17:20:28 +08:00
										 |  |  | There is a {github-code}/spring-boot-samples/spring-boot-sample-liquibase[Liquibase sample] | 
					
						
							|  |  |  | so you can see how to set things up. | 
					
						
							| 
									
										
										
										
											2014-04-18 05:59:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 17:39:40 +08:00
										 |  |  | [[howto-messaging]] | 
					
						
							|  |  |  | == Messaging | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-jms-disable-transaction]] | 
					
						
							|  |  |  | === Disable transacted JMS session | 
					
						
							|  |  |  | If your JMS broker does not support transacted session, you will have to disable the | 
					
						
							|  |  |  | support of transactions altogether. If you create your own `JmsListenerContainerFactory` | 
					
						
							|  |  |  | there is nothing to do since it won't be transacted by default. If you want to use | 
					
						
							|  |  |  | the `DefaultJmsListenerContainerFactoryConfigurer` to reuse Spring Boot's default, you | 
					
						
							|  |  |  | can disable transacted session as follows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@Bean | 
					
						
							|  |  |  | 	public DefaultJmsListenerContainerFactory jmsListenerContainerFactory( | 
					
						
							|  |  |  | 			ConnectionFactory connectionFactory, | 
					
						
							|  |  |  | 			DefaultJmsListenerContainerFactoryConfigurer configurer) { | 
					
						
							|  |  |  | 		DefaultJmsListenerContainerFactory listenerFactory = | 
					
						
							|  |  |  | 				new DefaultJmsListenerContainerFactory(); | 
					
						
							|  |  |  | 		configurer.configure(listenerFactory, connectionFactory); | 
					
						
							|  |  |  | 		listenerFactory.setTransactionManager(null); | 
					
						
							|  |  |  | 		listenerFactory.setSessionTransacted(false); | 
					
						
							|  |  |  | 		return listenerFactory; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This overrides the default factory and this should be applied to any other factory that | 
					
						
							|  |  |  | your application defines, if any. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-batch-applications]] | 
					
						
							|  |  |  | == Batch applications | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 17:08:40 +08:00
										 |  |  | NOTE: By default, batch applications require a `DataSource` to store job details. If you | 
					
						
							|  |  |  | want to deviate from that, you'll need to implement `BatchConfigurer`, see | 
					
						
							|  |  |  | {spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The | 
					
						
							| 
									
										
										
										
											2017-02-28 05:56:17 +08:00
										 |  |  | Javadoc of `@EnableBatchProcessing`] for more details. | 
					
						
							| 
									
										
										
										
											2017-02-13 17:08:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-execute-spring-batch-jobs-on-startup]] | 
					
						
							|  |  |  | === Execute Spring Batch jobs on startup | 
					
						
							| 
									
										
										
										
											2015-11-30 17:47:25 +08:00
										 |  |  | Spring Batch auto-configuration is enabled by adding `@EnableBatchProcessing` | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | (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 | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | `spring.batch.job.names` (comma-separated job name patterns). | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:53:47 +08:00
										 |  |  | _<<production-ready-features.adoc#production-ready-customizing-management-server-port>>_ | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | in the '`Production-ready features`' section. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-customize-the-whitelabel-error-page]] | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | === Customize the '`whitelabel`' error page | 
					
						
							|  |  |  | Spring Boot installs a '`whitelabel`' error page that you will see in browser client if | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | you encounter a server error (machine clients consuming JSON and other media types should | 
					
						
							| 
									
										
										
										
											2016-04-19 19:17:23 +08:00
										 |  |  | see a sensible response with the right error code). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NOTE: Set `server.error.whitelabel.enabled=false` to switch the default error page off | 
					
						
							|  |  |  | which will restore the default of the servlet container that you are using. Note that | 
					
						
							|  |  |  | Spring Boot will still attempt to resolve the error view so you'd probably add you own | 
					
						
							|  |  |  | error page rather than disabling it completely. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Overriding the error page with your own depends on the templating technology that you are | 
					
						
							|  |  |  | using. For example, if you are using Thymeleaf you would add an `error.html` template and | 
					
						
							|  |  |  | if you are using FreeMarker you would add an `error.ftl` 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 | 
					
						
							| 
									
										
										
										
											2017-04-29 14:30:06 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/web/servlet/error/ErrorMvcAutoConfiguration.{sc-ext}[`ErrorMvcAutoConfiguration`] for more options. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 19:14:58 +08:00
										 |  |  | See also the section on <<boot-features-error-handling, Error Handling>> for details of | 
					
						
							|  |  |  | how to register handlers in the servlet container. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 00:38:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[howto-use-actuator-with-jersey]] | 
					
						
							|  |  |  | === Actuator and Jersey | 
					
						
							|  |  |  | Actuator HTTP endpoints are only available for Spring MVC-based applications. If you want | 
					
						
							|  |  |  | to use Jersey and still use the actuator you will need to enable Spring MVC (by depending | 
					
						
							|  |  |  | on `spring-boot-starter-web`, for example). By default, both Jersey and the Spring MVC | 
					
						
							|  |  |  | dispatcher servlet are mapped to the same path (`/`). You will need to change the path for | 
					
						
							| 
									
										
										
										
											2017-01-27 04:43:04 +08:00
										 |  |  | one of them (by configuring `server.servlet.path` for Spring MVC or | 
					
						
							| 
									
										
										
										
											2015-11-23 00:38:38 +08:00
										 |  |  | `spring.jersey.application-path` for Jersey). For example, if you add | 
					
						
							| 
									
										
										
										
											2017-01-27 04:43:04 +08:00
										 |  |  | `server.servlet.path=/system` into `application.properties`, the actuator HTTP endpoints | 
					
						
							| 
									
										
										
										
											2015-11-23 00:38:38 +08:00
										 |  |  | will be available under `/system`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2016-07-27 23:16:19 +08:00
										 |  |  | it will switch off the default webapp security settings in Spring Boot (but leave the | 
					
						
							|  |  |  | Actuator's security enabled). To tweak the defaults try setting properties in | 
					
						
							|  |  |  | `+security.*+` (see | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | {sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`] | 
					
						
							| 
									
										
										
										
											2014-03-25 06:01:28 +08:00
										 |  |  | for details of available settings) and `SECURITY` section of | 
					
						
							|  |  |  | <<common-application-properties-security,Common application properties>>. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-03-25 06:01:28 +08:00
										 |  |  | 		public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { | 
					
						
							|  |  |  | 				auth.inMemoryAuthentication() | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | 					.withUser("barry").password("password").roles("USER"); // ... etc. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// ... other stuff for application security | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-07 12:44:20 +08:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 02:35:16 +08:00
										 |  |  | If you experience instantiation issues (e.g. using JDBC or JPA for the user detail store) | 
					
						
							|  |  |  | it might be worth extracting the `AuthenticationManagerBuilder` callback into a | 
					
						
							|  |  |  | `GlobalAuthenticationConfigurerAdapter` (in the `init()` method so it happens before the | 
					
						
							|  |  |  | authentication manager is needed elsewhere), e.g. | 
					
						
							| 
									
										
										
										
											2014-09-05 23:30:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-05 23:33:32 +08:00
										 |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-09-16 02:35:16 +08:00
										 |  |  | 	@Configuration | 
					
						
							| 
									
										
										
										
											2015-10-27 15:58:00 +08:00
										 |  |  | 	public class AuthenticationManagerConfiguration extends | 
					
						
							| 
									
										
										
										
											2015-10-27 16:20:16 +08:00
										 |  |  | 			GlobalAuthenticationConfigurerAdapter { | 
					
						
							| 
									
										
										
										
											2014-09-16 02:35:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		@Override | 
					
						
							|  |  |  | 		public void init(AuthenticationManagerBuilder auth) { | 
					
						
							|  |  |  | 			auth.inMemoryAuthentication() // ... etc. | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-09-05 23:33:32 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-04-07 12:44:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[howto-enable-https]] | 
					
						
							| 
									
										
										
										
											2014-04-24 06:24:59 +08:00
										 |  |  | === Enable HTTPS when running behind a proxy server | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | Ensuring that all your main endpoints are only available over HTTPS is an important | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | chore for any application. If you are using Tomcat as a servlet container, then | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:24:59 +08:00
										 |  |  | 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. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | [source,properties,indent=0] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-03-17 15:04:57 +08:00
										 |  |  | 	server.tomcat.remote_ip_header=x-forwarded-for | 
					
						
							|  |  |  | 	server.tomcat.protocol_header=x-forwarded-proto | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (The presence of either of those properties will switch on the valve. Or you can add the | 
					
						
							| 
									
										
										
										
											2017-04-28 22:48:47 +08:00
										 |  |  | `RemoteIpValve` yourself by adding a `TomcatServletWebServerFactory` bean.) | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-11-20 18:49:26 +08:00
										 |  |  | `security.require_ssl` to `true` in `application.properties`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-hotswapping]] | 
					
						
							|  |  |  | == Hot swapping | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-reload-static-content]] | 
					
						
							|  |  |  | === Reload static content | 
					
						
							| 
									
										
										
										
											2016-02-12 00:52:38 +08:00
										 |  |  | There are several options for hot reloading. The recommended approach is to use | 
					
						
							|  |  |  | <<using-spring-boot.adoc#using-boot-devtools,`spring-boot-devtools`>> as it provides | 
					
						
							|  |  |  | additional development-time features such as support for fast application restarts | 
					
						
							|  |  |  | and LiveReload as well as sensible development-time configuration (e.g. template caching). | 
					
						
							| 
									
										
										
										
											2017-02-08 17:37:29 +08:00
										 |  |  | Devtools works by monitoring the classpath for changes. This means that static resource | 
					
						
							|  |  |  | changes must be "built" for the change to take affect. By default, this happens | 
					
						
							|  |  |  | automatically in Eclipse when you save your changes. In IntelliJ IDEA, Make Project will | 
					
						
							|  |  |  | trigger the necessary build. Due to the | 
					
						
							|  |  |  | <<using-spring-boot.adoc#using-boot-devtools-restart-exclude, default restart | 
					
						
							|  |  |  | exclusions>>, changes to static resources will not trigger a restart of your application. | 
					
						
							|  |  |  | They will, however, trigger a live reload. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-12 00:52:38 +08:00
										 |  |  | Alternatively, 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). | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-20 20:29:16 +08:00
										 |  |  | Finally, the <<build-tool-plugins.adoc#build-tool-plugins, Maven and Gradle plugins>> can | 
					
						
							| 
									
										
										
										
											2016-02-12 00:52:38 +08:00
										 |  |  | be configured (see the `addResources` property) to support running from the command line | 
					
						
							| 
									
										
										
										
											2017-02-08 17:37:29 +08:00
										 |  |  | with reloading of static files directly from source. You can use that with an external | 
					
						
							|  |  |  | css/js compiler process if you are writing that code with higher level tools. | 
					
						
							| 
									
										
										
										
											2015-10-20 20:29:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-reload-thymeleaf-template-content]] | 
					
						
							|  |  |  | === Reload templates without restarting the container | 
					
						
							|  |  |  | Most of the templating technologies supported by Spring Boot include a configuration | 
					
						
							|  |  |  | option to disable caching (see below for details). If you're using the | 
					
						
							|  |  |  | `spring-boot-devtools` module these properties will be | 
					
						
							|  |  |  | <<using-spring-boot.adoc#using-boot-devtools-property-defaults,automatically configured>> | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | for you at development time. | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-reload-thymeleaf-content]] | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | ==== Thymeleaf templates | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | If you are using Thymeleaf, then set `spring.thymeleaf.cache` to `false`. See | 
					
						
							|  |  |  | {sc-spring-boot-autoconfigure}/thymeleaf/ThymeleafAutoConfiguration.{sc-ext}[`ThymeleafAutoConfiguration`] | 
					
						
							| 
									
										
										
										
											2014-04-30 00:46:55 +08:00
										 |  |  | for other Thymeleaf customization options. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 00:46:55 +08:00
										 |  |  | [[howto-reload-freemarker-content]] | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | ==== FreeMarker templates | 
					
						
							| 
									
										
										
										
											2014-04-30 00:46:55 +08:00
										 |  |  | If you are using FreeMarker, then set `spring.freemarker.cache` to `false`. See | 
					
						
							|  |  |  | {sc-spring-boot-autoconfigure}/freemarker/FreeMarkerAutoConfiguration.{sc-ext}[`FreeMarkerAutoConfiguration`] | 
					
						
							|  |  |  | for other FreeMarker customization options. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 22:28:27 +08:00
										 |  |  | [[howto-reload-groovy-template-content]] | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | ==== Groovy templates | 
					
						
							| 
									
										
										
										
											2014-05-16 22:28:27 +08:00
										 |  |  | If you are using Groovy templates, then set `spring.groovy.template.cache` to `false`. See | 
					
						
							|  |  |  | {sc-spring-boot-autoconfigure}/groovy/template/GroovyTemplateAutoConfiguration.{sc-ext}[`GroovyTemplateAutoConfiguration`] | 
					
						
							|  |  |  | for other Groovy customization options. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 20:13:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | [[howto-reload-fast-restart]] | 
					
						
							|  |  |  | === Fast application restarts | 
					
						
							|  |  |  | The `spring-boot-devtools` module includes support for automatic application restarts. | 
					
						
							|  |  |  | Whilst not as fast a technologies such as http://zeroturnaround.com/software/jrebel/[JRebel] | 
					
						
							|  |  |  | or https://github.com/spring-projects/spring-loaded[Spring Loaded] it's usually | 
					
						
							| 
									
										
										
										
											2015-06-11 15:33:09 +08:00
										 |  |  | significantly faster than a "`cold start`". You should probably give it a try before | 
					
						
							| 
									
										
										
										
											2015-07-11 23:06:24 +08:00
										 |  |  | investigating some of the more complex reload options discussed below. | 
					
						
							| 
									
										
										
										
											2015-06-11 13:06:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | For more details see the <<using-spring-boot.adoc#using-boot-devtools>> section. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-reload-java-classes-without-restarting]] | 
					
						
							|  |  |  | === Reload Java classes without restarting the container | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | Modern IDEs (Eclipse, IDEA, etc.) all support hot swapping of bytecode, so if you make a | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 01:22:35 +08:00
										 |  |  | [[howto-reload-springloaded-maven]] | 
					
						
							|  |  |  | ==== Configuring Spring Loaded for use with Maven | 
					
						
							| 
									
										
										
										
											2014-10-29 07:34:57 +08:00
										 |  |  | To use Spring Loaded with the Maven command line, just add it as a dependency in the | 
					
						
							| 
									
										
										
										
											2014-10-28 01:22:35 +08:00
										 |  |  | Spring Boot plugin declaration, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2014-10-29 07:34:57 +08:00
										 |  |  | 	<plugin> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 		<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 		<dependencies> | 
					
						
							|  |  |  | 			<dependency> | 
					
						
							|  |  |  | 				<groupId>org.springframework</groupId> | 
					
						
							|  |  |  | 				<artifactId>springloaded</artifactId> | 
					
						
							| 
									
										
										
										
											2017-01-10 21:57:49 +08:00
										 |  |  | 				<version>1.2.6.RELEASE</version> | 
					
						
							| 
									
										
										
										
											2014-10-29 07:34:57 +08:00
										 |  |  | 			</dependency> | 
					
						
							|  |  |  | 		</dependencies> | 
					
						
							|  |  |  | 	</plugin> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-12 23:08:50 +08:00
										 |  |  | This normally works pretty well with Eclipse and IntelliJ IDEA as long as they have their | 
					
						
							| 
									
										
										
										
											2014-10-29 07:34:57 +08:00
										 |  |  | build configuration aligned with the Maven defaults (Eclipse m2e does this out of the | 
					
						
							|  |  |  | box). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 01:22:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-12 23:08:50 +08:00
										 |  |  | [[howto-reload-springloaded-gradle-and-intellij-idea]] | 
					
						
							|  |  |  | ==== Configuring Spring Loaded for use with Gradle and IntelliJ IDEA | 
					
						
							| 
									
										
										
										
											2014-09-05 17:34:20 +08:00
										 |  |  | You need to jump through a few hoops if you want to use Spring Loaded in combination with | 
					
						
							| 
									
										
										
										
											2015-06-12 23:08:50 +08:00
										 |  |  | Gradle and IntelliJ IDEA. By default, IntelliJ IDEA will compile classes into a different | 
					
						
							|  |  |  | location than Gradle, causing Spring Loaded monitoring to fail. | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-12 23:08:50 +08:00
										 |  |  | To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin: | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	buildscript { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 		repositories { | 
					
						
							|  |  |  | 			jcenter() | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | 		dependencies { | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 			classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}' | 
					
						
							| 
									
										
										
										
											2017-01-10 22:07:58 +08:00
										 |  |  | 			classpath 'org.springframework:springloaded:1.2.6.RELEASE' | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	apply plugin: 'idea' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idea { | 
					
						
							|  |  |  | 		module { | 
					
						
							|  |  |  | 			inheritOutputDirs = false | 
					
						
							|  |  |  | 			outputDir = file("$buildDir/classes/main/") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-12 23:08:50 +08:00
										 |  |  | NOTE: IntelliJ IDEA must be configured to use the same Java version as the command line | 
					
						
							|  |  |  | Gradle task and `springloaded` *must* be included as a `buildscript` dependency. | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 20:36:41 +08:00
										 |  |  | You can also additionally enable '`Make Project Automatically`' inside  IntelliJ IDEA to | 
					
						
							| 
									
										
										
										
											2014-06-10 08:27:33 +08:00
										 |  |  | automatically compile your code whenever a file is saved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[howto-build]] | 
					
						
							|  |  |  | == Build | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-24 19:55:56 +08:00
										 |  |  | [[howto-build-info]] | 
					
						
							|  |  |  | === Generate build information | 
					
						
							|  |  |  | Both the Maven and Gradle plugin allow to generate build information containing | 
					
						
							|  |  |  | the coordinates, name and version of the project. The plugin can also be configured | 
					
						
							|  |  |  | to add additional properties through configuration. When such file is present, | 
					
						
							|  |  |  | Spring Boot auto-configures a `BuildProperties` bean. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To generate build information with Maven, add an execution for the `build-info` goal: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 				<version>{spring-boot-version}</version> | 
					
						
							|  |  |  | 				<executions> | 
					
						
							|  |  |  | 					<execution> | 
					
						
							|  |  |  | 						<goals> | 
					
						
							|  |  |  | 							<goal>build-info</goal> | 
					
						
							|  |  |  | 						</goals> | 
					
						
							|  |  |  | 					</execution> | 
					
						
							|  |  |  | 				</executions> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TIP: Check the {spring-boot-maven-plugin-site}/[Spring Boot Maven Plugin documentation] | 
					
						
							|  |  |  | for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | And to do the same with Gradle: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | 	springBoot { | 
					
						
							| 
									
										
										
										
											2016-03-24 19:55:56 +08:00
										 |  |  | 		buildInfo() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Additional properties can be added using the DSL: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	springBoot  { | 
					
						
							|  |  |  | 		buildInfo { | 
					
						
							|  |  |  | 			additionalProperties = [ | 
					
						
							|  |  |  | 				'foo': 'bar' | 
					
						
							|  |  |  | 			] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[howto-git-info]] | 
					
						
							|  |  |  | === Generate git information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Both Maven and Gradle allow to generate a `git.properties` file containing information | 
					
						
							|  |  |  | about the state of your `git` source code repository when the project was built. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For Maven users the `spring-boot-starter-parent` POM includes a pre-configured plugin to | 
					
						
							|  |  |  | generate a `git.properties` file. Simply add the following declaration to your POM: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>pl.project13.maven</groupId> | 
					
						
							|  |  |  | 				<artifactId>git-commit-id-plugin</artifactId> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Gradle users can achieve the same result using the | 
					
						
							|  |  |  | https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties[`gradle-git-properties`] plugin | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	plugins { | 
					
						
							| 
									
										
										
										
											2017-02-13 17:17:45 +08:00
										 |  |  | 		id "com.gorylenko.gradle-git-properties" version "1.4.17" | 
					
						
							| 
									
										
										
										
											2016-03-24 19:55:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:01:21 +08:00
										 |  |  | [[howto-customize-dependency-versions-with-maven]] | 
					
						
							| 
									
										
										
										
											2015-08-03 23:37:25 +08:00
										 |  |  | [[howto-customize-dependency-versions]] | 
					
						
							|  |  |  | === Customize dependency versions | 
					
						
							| 
									
										
										
										
											2014-06-05 22:37:35 +08:00
										 |  |  | If you use a Maven build that inherits directly or indirectly from `spring-boot-dependencies` | 
					
						
							|  |  |  | (for instance `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-boot-dependencies`] | 
					
						
							| 
									
										
										
										
											2014-04-24 06:01:21 +08:00
										 |  |  | 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> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 03:47:19 +08:00
										 |  |  | NOTE: This only works if your Maven project inherits (directly or indirectly) from | 
					
						
							| 
									
										
										
										
											2014-06-05 22:37:35 +08:00
										 |  |  | `spring-boot-dependencies`. If you have added `spring-boot-dependencies` in your | 
					
						
							|  |  |  | own `dependencyManagement` section with `<scope>import</scope>` you have to redefine | 
					
						
							| 
									
										
										
										
											2015-08-03 23:37:25 +08:00
										 |  |  | the artifact yourself instead of overriding the property. | 
					
						
							| 
									
										
										
										
											2014-06-05 22:37:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:01:21 +08:00
										 |  |  | WARNING: Each Spring Boot release is designed and tested against a specific set of | 
					
						
							| 
									
										
										
										
											2014-05-23 10:18:08 +08:00
										 |  |  | third-party dependencies. Overriding versions may cause compatibility issues. | 
					
						
							| 
									
										
										
										
											2014-04-24 06:01:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 23:37:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:01:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 23:10:06 +08:00
										 |  |  | [[howto-create-an-executable-jar-with-maven]] | 
					
						
							|  |  |  | === Create an executable JAR with Maven | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | The `spring-boot-maven-plugin` can be used to create an executable '`fat`' JAR. If you | 
					
						
							| 
									
										
										
										
											2014-05-08 23:10:06 +08:00
										 |  |  | are using the `spring-boot-starter-parent` POM you can simply declare the plugin and | 
					
						
							|  |  |  | your jars will be repackaged: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you are not using the parent POM you can still use the plugin, however, you must | 
					
						
							|  |  |  | additionally add an `<executions>` section: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 				<version>{spring-boot-version}</version> | 
					
						
							|  |  |  | 				<executions> | 
					
						
							|  |  |  | 					<execution> | 
					
						
							|  |  |  | 						<goals> | 
					
						
							|  |  |  | 							<goal>repackage</goal> | 
					
						
							|  |  |  | 						</goals> | 
					
						
							|  |  |  | 					</execution> | 
					
						
							|  |  |  | 				</executions> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See the {spring-boot-maven-plugin-site}/usage.html[plugin documentation] for full usage | 
					
						
							|  |  |  | details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | [[howto-create-an-additional-executable-jar]] | 
					
						
							| 
									
										
										
										
											2016-09-19 20:58:39 +08:00
										 |  |  | === Use a Spring Boot application as a dependency | 
					
						
							|  |  |  | Like a war file, a Spring Boot application is not intended to be used as a dependency. If | 
					
						
							|  |  |  | your application contains classes that you want to share with other projects, the | 
					
						
							|  |  |  | recommended approach is to move that code into a separate module. The separate module can | 
					
						
							|  |  |  | then be depended upon by your application and other projects. | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-19 20:58:39 +08:00
										 |  |  | If you cannot rearrange your code as recommended above, Spring Boot's Maven and Gradle | 
					
						
							|  |  |  | plugins must be configured to produce a separate artifact that is suitable for use as a | 
					
						
							|  |  |  | dependency. The executable archive cannot be used as a dependency as the | 
					
						
							| 
									
										
										
										
											2016-10-02 13:00:47 +08:00
										 |  |  | <<appendix-executable-jar-format.adoc#executable-jar-jar-file-structure,executable jar | 
					
						
							| 
									
										
										
										
											2016-09-19 20:58:39 +08:00
										 |  |  | format>> packages application classes in `BOOT-INF/classes`. This means | 
					
						
							|  |  |  | that they cannot be found when the executable jar is used as a dependency. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To produce the two artifacts, one that can be used as a dependency and one that is | 
					
						
							|  |  |  | executable, a classifier must be specified. This classifier is applied to the name of the | 
					
						
							|  |  |  | executable archive, leaving the default archive for use as dependency. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To configure a classifier of `exec` in Maven, the following configuration can be used: | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 				<configuration> | 
					
						
							|  |  |  | 					<classifier>exec</classifier> | 
					
						
							|  |  |  | 				</configuration> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 10:41:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 15:35:01 +08:00
										 |  |  | [[howto-extract-specific-libraries-when-an-executable-jar-runs]] | 
					
						
							|  |  |  | === Extract specific libraries when an executable jar runs | 
					
						
							|  |  |  | Most nested libraries in an executable jar do not need to be unpacked in order to run, | 
					
						
							|  |  |  | however, certain libraries can have problems. For example, JRuby includes its own nested | 
					
						
							|  |  |  | jar support which assumes that the `jruby-complete.jar` is always directly available as a | 
					
						
							|  |  |  | file in its own right. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To deal with any problematic libraries, you can flag that specific nested jars should be | 
					
						
							| 
									
										
										
										
											2014-10-10 02:06:46 +08:00
										 |  |  | automatically unpacked to the '`temp folder`' when the executable jar first runs. | 
					
						
							| 
									
										
										
										
											2014-06-24 15:35:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | For example, to indicate that JRuby should be flagged for unpack using the Maven Plugin | 
					
						
							|  |  |  | you would add the following configuration: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 				<configuration> | 
					
						
							|  |  |  | 					<requiresUnpack> | 
					
						
							|  |  |  | 						<dependency> | 
					
						
							|  |  |  | 							<groupId>org.jruby</groupId> | 
					
						
							|  |  |  | 							<artifactId>jruby-complete</artifactId> | 
					
						
							|  |  |  | 						</dependency> | 
					
						
							|  |  |  | 					</requiresUnpack> | 
					
						
							|  |  |  | 				</configuration> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | [[howto-create-a-nonexecutable-jar]] | 
					
						
							|  |  |  | === Create a non-executable JAR with exclusions | 
					
						
							| 
									
										
										
										
											2014-06-24 10:41:22 +08:00
										 |  |  | Often if you have an executable and a non-executable jar as build products, the executable | 
					
						
							|  |  |  | version will have additional configuration files that are not needed in a library jar. | 
					
						
							|  |  |  | E.g. the `application.yml` configuration file might excluded from the non-executable JAR. | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-29 18:28:14 +08:00
										 |  |  | The `maven-jar-plugin` used to expose a `forceCreation` attribute that allows you to | 
					
						
							|  |  |  | create the jar _again_ once the `repackage` goal has ran. Arguably, this was a bit fragile | 
					
						
							|  |  |  | anyway since it was relying on the order of plugin executions. In Maven, the executable | 
					
						
							|  |  |  | jar must be the main artifact and you can add a classified jar for the library: | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<build> | 
					
						
							|  |  |  | 		<plugins> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 				<artifactId>spring-boot-maven-plugin</artifactId> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 			<plugin> | 
					
						
							|  |  |  | 				<artifactId>maven-jar-plugin</artifactId> | 
					
						
							|  |  |  | 				<executions> | 
					
						
							|  |  |  | 					<execution> | 
					
						
							| 
									
										
										
										
											2016-11-29 18:28:14 +08:00
										 |  |  | 						<id>lib</id> | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 						<phase>package</phase> | 
					
						
							|  |  |  | 						<goals> | 
					
						
							|  |  |  | 							<goal>jar</goal> | 
					
						
							|  |  |  | 						</goals> | 
					
						
							|  |  |  | 						<configuration> | 
					
						
							| 
									
										
										
										
											2016-11-29 18:28:14 +08:00
										 |  |  | 							<classifier>lib</classifier> | 
					
						
							| 
									
										
										
										
											2014-06-23 18:00:03 +08:00
										 |  |  | 							<excludes> | 
					
						
							|  |  |  | 								<exclude>application.yml</exclude> | 
					
						
							|  |  |  | 							</excludes> | 
					
						
							|  |  |  | 						</configuration> | 
					
						
							|  |  |  | 					</execution> | 
					
						
							|  |  |  | 				</executions> | 
					
						
							|  |  |  | 			</plugin> | 
					
						
							|  |  |  | 		</plugins> | 
					
						
							|  |  |  | 	</build> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 10:41:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 06:09:53 +08:00
										 |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-06-03 19:52:49 +08:00
										 |  |  | the `jvmArguments` property of the {spring-boot-maven-plugin-site}/[maven plugin]. | 
					
						
							| 
									
										
										
										
											2014-04-24 06:09:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-03 19:52:49 +08:00
										 |  |  | Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for more details. | 
					
						
							| 
									
										
										
										
											2014-04-24 06:09:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | [[howto-build-an-executable-archive-with-ant]] | 
					
						
							| 
									
										
										
										
											2015-06-27 06:09:59 +08:00
										 |  |  | === Build an executable archive from Ant without using spring-boot-antlib | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | To build with Ant you need to grab dependencies, compile and then create a jar or war | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | archive. To make it executable you can either use the `spring-boot-antlib` | 
					
						
							| 
									
										
										
										
											2015-06-27 06:09:59 +08:00
										 |  |  | module, or you can follow these instructions: | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | . If you are building a jar, package the application's classes and resources in a nested | 
					
						
							|  |  |  |   `BOOT-INF/classes` directory. If you are building a war, package the application's | 
					
						
							|  |  |  |   classes in a nested `WEB-INF/classes` directory as usual. | 
					
						
							|  |  |  | . Add the runtime dependencies in a nested `BOOT-INF/lib` directory for a jar or | 
					
						
							|  |  |  |   `WEB-INF/lib` for a war. Remember *not* to compress the entries in the archive. | 
					
						
							|  |  |  | . Add the `provided` (embedded container) dependencies in a nested `BOOT-INF/lib` | 
					
						
							|  |  |  |   directory for jar or `WEB-INF/lib-provided` for a war. Remember *not* to compress the | 
					
						
							|  |  |  |   entries in the archive. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | . Add the `spring-boot-loader` classes at the root of the archive (so the `Main-Class` | 
					
						
							|  |  |  |   is available). | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | . Use the appropriate launcher, e.g. `JarLauncher` for a jar file, as a `Main-Class` | 
					
						
							|  |  |  |   attribute in the manifest and specify the other properties it needs as manifest entries, | 
					
						
							|  |  |  |   principally a `Start-Class`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Example: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | [source,xml,indent=0] | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 	<target name="build" depends="compile"> | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | 		<jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false"> | 
					
						
							|  |  |  | 			<mappedresources> | 
					
						
							|  |  |  | 				<fileset dir="target/classes" /> | 
					
						
							|  |  |  | 				<globmapper from="*" to="BOOT-INF/classes/*"/> | 
					
						
							|  |  |  | 			</mappedresources> | 
					
						
							|  |  |  | 			<mappedresources> | 
					
						
							|  |  |  | 				<fileset dir="src/main/resources" erroronmissingdir="false"/> | 
					
						
							|  |  |  | 				<globmapper from="*" to="BOOT-INF/classes/*"/> | 
					
						
							|  |  |  | 			</mappedresources> | 
					
						
							|  |  |  | 			<mappedresources> | 
					
						
							|  |  |  | 				<fileset dir="${lib.dir}/runtime" /> | 
					
						
							|  |  |  | 				<globmapper from="*" to="BOOT-INF/lib/*"/> | 
					
						
							|  |  |  | 			</mappedresources> | 
					
						
							|  |  |  | 			<zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" /> | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 			<manifest> | 
					
						
							|  |  |  | 				<attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" /> | 
					
						
							|  |  |  | 				<attribute name="Start-Class" value="${start-class}" /> | 
					
						
							|  |  |  | 			</manifest> | 
					
						
							|  |  |  | 		</jar> | 
					
						
							|  |  |  | 	</target> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | The {github-code}/spring-boot-samples/spring-boot-sample-ant[Ant Sample] has a | 
					
						
							|  |  |  | `build.xml` with a `manual` task that should work if you run it with | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2016-04-06 17:56:25 +08:00
										 |  |  | 	$ ant -lib <folder containing ivy-2.2.jar> clean manual | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2015-01-29 20:35:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The first step in producing a deployable war file is to provide a | 
					
						
							|  |  |  | `SpringBootServletInitializer` subclass and override its `configure` method. This makes | 
					
						
							|  |  |  | use of Spring Framework's Servlet 3.0 support and allows you to configure your | 
					
						
							|  |  |  | application when it's launched by the servlet container. Typically, you update your | 
					
						
							|  |  |  | application's main class to extend `SpringBootServletInitializer`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-01-29 20:42:49 +08:00
										 |  |  | 	@SpringBootApplication | 
					
						
							| 
									
										
										
										
											2015-01-29 20:35:48 +08:00
										 |  |  | 	public class Application extends SpringBootServletInitializer { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		@Override | 
					
						
							|  |  |  | 		protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | 
					
						
							|  |  |  | 			return application.sources(Application.class); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		public static void main(String[] args) throws Exception { | 
					
						
							|  |  |  | 			SpringApplication.run(Application.class, args); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The next step is to update your build configuration so that your project produces a war file | 
					
						
							|  |  |  | rather than a jar file. If you're using Maven and using `spring-boot-starter-parent` (which | 
					
						
							| 
									
										
										
										
											2017-01-31 20:39:58 +08:00
										 |  |  | configures Maven's war plugin for you) all you need to do is to modify `pom.xml` to change the | 
					
						
							| 
									
										
										
										
											2015-01-29 20:35:48 +08:00
										 |  |  | packaging to war: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<packaging>war</packaging> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you're using Gradle, you need to modify `build.gradle` to apply the war plugin to the | 
					
						
							|  |  |  | project: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	apply plugin: 'war' | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The final step in the process is to ensure that the embedded servlet container doesn't | 
					
						
							|  |  |  | interfere with the servlet container to which the war file will be deployed. To do so, you | 
					
						
							|  |  |  | need to mark the embedded servlet container dependency as provided. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you're using Maven: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependencies> | 
					
						
							|  |  |  | 		<!-- … --> | 
					
						
							|  |  |  | 		<dependency> | 
					
						
							|  |  |  | 			<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 			<artifactId>spring-boot-starter-tomcat</artifactId> | 
					
						
							|  |  |  | 			<scope>provided</scope> | 
					
						
							|  |  |  | 		</dependency> | 
					
						
							|  |  |  | 		<!-- … --> | 
					
						
							|  |  |  | 	</dependencies> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | And if you're using Gradle: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	dependencies { | 
					
						
							|  |  |  | 		// … | 
					
						
							|  |  |  | 		providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' | 
					
						
							|  |  |  | 		// … | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-05 19:25:48 +08:00
										 |  |  | NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration as, among other | 
					
						
							| 
									
										
										
										
											2017-03-15 04:51:23 +08:00
										 |  |  | limitations, `compileOnly` dependencies are not on the test classpath so any web-based | 
					
						
							|  |  |  | integration tests will fail. | 
					
						
							| 
									
										
										
										
											2016-07-19 22:40:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 20:35:48 +08:00
										 |  |  | If you're using the <<build-tool-plugins.adoc#build-tool-plugins, Spring Boot build tools>>, | 
					
						
							|  |  |  | marking the embedded servlet container dependency as provided will produce an executable war | 
					
						
							|  |  |  | file with the provided dependencies packaged in a `lib-provided` directory. This means | 
					
						
							|  |  |  | that, in addition to being deployable to a servlet container, you can also run your | 
					
						
							|  |  |  | application using `java -jar` on the command line. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TIP: Take a look at Spring Boot's sample applications for a | 
					
						
							|  |  |  | {github-code}/spring-boot-samples/spring-boot-sample-traditional/pom.xml[Maven-based example] | 
					
						
							|  |  |  | of the above-described configuration. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[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 | 
					
						
							| 
									
										
										
										
											2014-05-15 16:15:35 +08:00
										 |  |  | and/or jar. Useful reading is in the http://spring.io/guides/gs/convert-jar-to-war/[Getting | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | Started Guide on Converting a jar to a war]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Create a deployable war by extending `SpringBootServletInitializer` (e.g. in a class | 
					
						
							| 
									
										
										
										
											2016-10-03 18:28:25 +08:00
										 |  |  | called `Application`), and add the Spring Boot `@SpringBootApplication` annotation. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | Example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2016-10-03 18:28:25 +08:00
										 |  |  | 	@SpringBootApplication | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 	public class Application extends SpringBootServletInitializer { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		@Override | 
					
						
							|  |  |  | 		protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | 
					
						
							| 
									
										
										
										
											2014-12-10 16:29:12 +08:00
										 |  |  | 			// Customize the application or call application.sources(...) to add sources | 
					
						
							| 
									
										
										
										
											2016-10-03 18:28:25 +08:00
										 |  |  | 			// Since our example is itself a @Configuration class (via @SpringBootApplication) | 
					
						
							|  |  |  | 			// we actually don't need to override this method. | 
					
						
							| 
									
										
										
										
											2014-12-10 16:29:12 +08:00
										 |  |  | 			return application; | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-03-14 23:31:57 +08:00
										 |  |  | `/META-INF/resources`) in the classpath root. Same for `messages.properties` (Spring Boot | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | detects this automatically in the root of the classpath). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Vanilla usage of Spring `DispatcherServlet` and Spring Security should require no further | 
					
						
							| 
									
										
										
										
											2014-03-18 22:34:06 +08:00
										 |  |  | 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, | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 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/>`. | 
					
						
							| 
									
										
										
										
											2017-03-02 16:54:34 +08:00
										 |  |  | * An `ApplicationContext` in an XML file can be added through an `@ImportResource` in | 
					
						
							|  |  |  |   your `Application`. Or simple cases where annotation configuration is heavily used | 
					
						
							|  |  |  |   already can be recreated in a few lines as `@Bean` definitions. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:28:25 +08:00
										 |  |  | [NOTE] | 
					
						
							|  |  |  | ==== | 
					
						
							|  |  |  | If you intend to start your application as a war or as an executable application, you | 
					
						
							|  |  |  | need to share the customizations of the builder in a method that is both available to the | 
					
						
							| 
									
										
										
										
											2016-11-05 11:11:02 +08:00
										 |  |  | `SpringBootServletInitializer` callback and the `main` method, something like: | 
					
						
							| 
									
										
										
										
											2016-10-03 18:28:25 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	@SpringBootApplication | 
					
						
							|  |  |  | 	public class Application extends SpringBootServletInitializer { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		@Override | 
					
						
							|  |  |  | 		protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { | 
					
						
							|  |  |  | 			return configureApplication(builder); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		public static void main(String[] args) { | 
					
						
							|  |  |  | 			configureApplication(new SpringApplicationBuilder()).run(args); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) { | 
					
						
							|  |  |  | 			return builder.sources(Application.class).bannerMode(Banner.Mode.OFF); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | ==== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | Applications can fall into more than one category: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 11:52:56 +08:00
										 |  |  | * Servlet 3.0+ applications with no `web.xml`. | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | * 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 11:52:56 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-03-14 04:28:16 +08:00
										 |  |  | `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. | 
					
						
							| 
									
										
										
										
											2014-11-04 01:04:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-08 12:10:51 +08:00
										 |  |  | [[howto-weblogic]] | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | ===  Deploying a WAR to WebLogic | 
					
						
							|  |  |  | To deploy a Spring Boot application to WebLogic you must ensure that your servlet | 
					
						
							| 
									
										
										
										
											2014-12-08 12:10:51 +08:00
										 |  |  | initializer *directly* implements `WebApplicationInitializer` (even if you extend from a | 
					
						
							|  |  |  | base class that already implements it). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | A typical initializer for WebLogic would be something like this: | 
					
						
							| 
									
										
										
										
											2014-12-08 12:10:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [source,java,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	import org.springframework.boot.autoconfigure.SpringBootApplication; | 
					
						
							|  |  |  | 	import org.springframework.boot.context.web.SpringBootServletInitializer; | 
					
						
							|  |  |  | 	import org.springframework.web.WebApplicationInitializer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@SpringBootApplication | 
					
						
							|  |  |  | 	public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-11 20:45:43 +08:00
										 |  |  | If you use logback, you will also need to tell WebLogic to prefer the packaged version | 
					
						
							| 
									
										
										
										
											2014-12-08 12:10:51 +08:00
										 |  |  | rather than the version that pre-installed with the server. You can do this by adding a | 
					
						
							|  |  |  | `WEB-INF/weblogic.xml` file with the following contents: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							| 
									
										
										
										
											2015-05-26 17:07:24 +08:00
										 |  |  | 	<?xml version="1.0" encoding="UTF-8"?> | 
					
						
							|  |  |  | 	<wls:weblogic-web-app | 
					
						
							|  |  |  | 		xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" | 
					
						
							|  |  |  | 		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
					
						
							|  |  |  | 		xsi:schemaLocation="http://java.sun.com/xml/ns/javaee | 
					
						
							|  |  |  | 			http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd | 
					
						
							|  |  |  | 			http://xmlns.oracle.com/weblogic/weblogic-web-app | 
					
						
							|  |  |  | 			http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd"> | 
					
						
							|  |  |  | 		<wls:container-descriptor> | 
					
						
							|  |  |  | 			<wls:prefer-application-packages> | 
					
						
							|  |  |  | 				<wls:package-name>org.slf4j</wls:package-name> | 
					
						
							|  |  |  | 			</wls:prefer-application-packages> | 
					
						
							|  |  |  | 		</wls:container-descriptor> | 
					
						
							|  |  |  | 	</wls:weblogic-web-app> | 
					
						
							| 
									
										
										
										
											2014-12-08 12:10:51 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-04 01:04:57 +08:00
										 |  |  | [[howto-servlet-2-5]] | 
					
						
							|  |  |  | ===  Deploying a WAR in an Old (Servlet 2.5) Container | 
					
						
							| 
									
										
										
										
											2015-02-22 16:48:29 +08:00
										 |  |  | Spring Boot uses Servlet 3.0 APIs to initialize the `ServletContext` (register `Servlets` | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | etc.)  so you can't use the same application out of the box in a Servlet 2.5 container. | 
					
						
							|  |  |  | It *is* however possible to run a Spring Boot application on an older container with some | 
					
						
							|  |  |  | special tools. If you include `org.springframework.boot:spring-boot-legacy` as a | 
					
						
							|  |  |  | dependency (https://github.com/scratches/spring-boot-legacy[maintained separately] to the | 
					
						
							| 
									
										
										
										
											2016-07-28 13:51:31 +08:00
										 |  |  | core of Spring Boot and currently available at 1.0.2.RELEASE), all you should need to do | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | is create a `web.xml` and declare a context listener to create the application context and | 
					
						
							|  |  |  | your filters and servlets. The context listener is a special purpose one for Spring Boot, | 
					
						
							|  |  |  | but the rest of it is normal for a Spring application in Servlet 2.5. Example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<?xml version="1.0" encoding="UTF-8"?> | 
					
						
							|  |  |  | 	<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" | 
					
						
							|  |  |  | 		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
					
						
							|  |  |  | 		xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		<context-param> | 
					
						
							|  |  |  | 			<param-name>contextConfigLocation</param-name> | 
					
						
							|  |  |  | 			<param-value>demo.Application</param-value> | 
					
						
							|  |  |  | 		</context-param> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		<listener> | 
					
						
							|  |  |  | 			<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class> | 
					
						
							|  |  |  | 		</listener> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		<filter> | 
					
						
							| 
									
										
										
										
											2016-10-12 16:03:23 +08:00
										 |  |  | 			<filter-name>metricsFilter</filter-name> | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | 			<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | 
					
						
							| 
									
										
										
										
											2014-12-19 16:13:30 +08:00
										 |  |  | 		</filter> | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		<filter-mapping> | 
					
						
							| 
									
										
										
										
											2016-10-12 16:03:23 +08:00
										 |  |  | 			<filter-name>metricsFilter</filter-name> | 
					
						
							| 
									
										
										
										
											2014-11-04 09:20:40 +08:00
										 |  |  | 			<url-pattern>/*</url-pattern> | 
					
						
							|  |  |  | 		</filter-mapping> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		<servlet> | 
					
						
							|  |  |  | 			<servlet-name>appServlet</servlet-name> | 
					
						
							|  |  |  | 			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | 
					
						
							|  |  |  | 			<init-param> | 
					
						
							|  |  |  | 				<param-name>contextAttribute</param-name> | 
					
						
							|  |  |  | 				<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value> | 
					
						
							|  |  |  | 			</init-param> | 
					
						
							|  |  |  | 			<load-on-startup>1</load-on-startup> | 
					
						
							|  |  |  | 		</servlet> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		<servlet-mapping> | 
					
						
							|  |  |  | 			<servlet-name>appServlet</servlet-name> | 
					
						
							|  |  |  | 			<url-pattern>/</url-pattern> | 
					
						
							|  |  |  | 		</servlet-mapping> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	</web-app> | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In this example we are using a single application context (the one created by the context | 
					
						
							|  |  |  | listener) and attaching it to the `DispatcherServlet` using an init parameter. This is | 
					
						
							| 
									
										
										
										
											2015-02-02 13:37:17 +08:00
										 |  |  | normal in a Spring Boot application (you normally only have one application context). | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 21:16:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | [[howto-use-lettuce-instead-of-jedis]] | 
					
						
							|  |  |  | === Use Lettuce instead of Jedis | 
					
						
							| 
									
										
										
										
											2017-05-02 21:16:11 +08:00
										 |  |  | The Spring Boot starter (`spring-boot-starter-data-redis`) uses | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | https://github.com/xetorthio/jedis/[Jedis] by default. You need to exclude that dependency | 
					
						
							| 
									
										
										
										
											2017-05-04 20:03:50 +08:00
										 |  |  | and include the https://github.com/lettuce-io/lettuce-core/[Lettuce] one instead. You also | 
					
						
							|  |  |  | need `commons-pool2`. Spring Boot manages these dependencies to help make this process as | 
					
						
							|  |  |  | easy as possible. | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Example in Maven: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,xml,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.springframework.boot</groupId> | 
					
						
							|  |  |  | 		<artifactId>spring-boot-starter-data-redis</artifactId> | 
					
						
							|  |  |  | 		<exclusions> | 
					
						
							|  |  |  | 			<exclusion> | 
					
						
							|  |  |  | 				<groupId>redis.clients</groupId> | 
					
						
							|  |  |  | 				<artifactId>jedis</artifactId> | 
					
						
							|  |  |  | 			</exclusion> | 
					
						
							|  |  |  | 		</exclusions> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							|  |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>io.lettuce</groupId> | 
					
						
							|  |  |  | 		<artifactId>lettuce-core</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							| 
									
										
										
										
											2017-05-04 20:03:50 +08:00
										 |  |  | 	<dependency> | 
					
						
							|  |  |  | 		<groupId>org.apache.commons</groupId> | 
					
						
							|  |  |  | 		<artifactId>commons-pool2</artifactId> | 
					
						
							|  |  |  | 	</dependency> | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example in Gradle: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [source,groovy,indent=0,subs="verbatim,quotes,attributes"] | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 	configurations { | 
					
						
							|  |  |  | 		compile.exclude module: "jedis" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dependencies { | 
					
						
							| 
									
										
										
										
											2017-05-04 20:03:50 +08:00
										 |  |  | 		compile("io.lettuce:lettuce-core") | 
					
						
							|  |  |  | 		compile("org.apache.commons:commons-pool2") | 
					
						
							| 
									
										
										
										
											2016-03-02 23:04:44 +08:00
										 |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-02 21:16:11 +08:00
										 |  |  | ---- |