|
|
|
# How Do I Do That With Spring Boot?
|
|
|
|
|
|
|
|
Here is a starting point for a potentially large collection of micro
|
|
|
|
HOWTO guides. If you want to add a placeholder for a question without
|
|
|
|
an answer, put it at the top (at header level 2) and we can fill in
|
|
|
|
the gaps later.
|
|
|
|
|
|
|
|
## Configure Tomcat
|
|
|
|
|
|
|
|
## Configure Jetty
|
|
|
|
|
|
|
|
## Test a Spring Boot Application
|
|
|
|
|
|
|
|
A Spring Boot application is just a Spring `ApplicationContext` so
|
|
|
|
nothing very special has to be done to test it beyond what you would
|
|
|
|
normally do with a vanilla Spring context. One thing to watch out for
|
|
|
|
though is that the external properties, logging and other features of
|
|
|
|
Spring Boot are only installed in the context by default if you use
|
|
|
|
`SpringApplication` to create it. Spring Boot has a special Spring
|
|
|
|
`TestContextLoader` which makes this job easy. For example (from the
|
|
|
|
JPA Sample):
|
|
|
|
|
|
|
|
```java
|
|
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
|
|
@ContextConfiguration(classes = SampleDataJpaApplication.class,
|
|
|
|
loader = SpringApplicationContextLoader.class)
|
|
|
|
public class CityRepositoryIntegrationTests {
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
CityRepository repository;
|
|
|
|
|
|
|
|
...
|
|
|
|
```
|
|
|
|
|
|
|
|
To use the `SpringApplicationContextLoader` you need the test jar on
|
|
|
|
your classpath (recommended Maven co-ordinates
|
|
|
|
"org.springframework.boot:spring-boot-starter-test"). The context
|
|
|
|
loader guesses whether you want to test a web application or not
|
|
|
|
(e.g. with `MockMVC`) by looking for the `@WebAppConfiguration`
|
|
|
|
annotation (`MockMVC` and `@WebAppConfiguration` are from the Spring
|
|
|
|
Test support library).
|
|
|
|
|
|
|
|
<span id="main.properties"/>
|
|
|
|
## 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
|
|
|
|
behaviour. Or you can externalize the configuration using properties
|
|
|
|
in `spring.main.*`. E.g. in `application.properties` you might have
|
|
|
|
|
|
|
|
```properties
|
|
|
|
spring.main.web_environment: false
|
|
|
|
spring.main.show_banner: false
|
|
|
|
```
|
|
|
|
|
|
|
|
and then the Spring Boot banner will not be printed on startup, and
|
|
|
|
the application will not be a web application.
|
|
|
|
|
|
|
|
## 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 web
|
|
|
|
depdendencies off the classpath. If you can't do that (e.g. you are
|
|
|
|
running 2 applications from the same code base) then you can
|
|
|
|
explicitly call `SpringApplication.setWebEnvironment(false)`, or set
|
|
|
|
the `applicationContextClass` property (through the Java API or with
|
|
|
|
[external properties](#main.properties)). Application code that you
|
|
|
|
want to run as your business logic can be implemented as a
|
|
|
|
`CommandLineRunner` and dropped into the context as a `@Bean`
|
|
|
|
definition.
|
|
|
|
|
|
|
|
## Create a Deployable WAR File
|
|
|
|
|
|
|
|
Use the `SpringBootServletInitializer` base class, which is picked up
|
|
|
|
by Spring's Servlet 3.0 support on deployment. Add an extension of
|
|
|
|
that to your project and build a WAR file as normal. For more detail,
|
|
|
|
see the ["Converting a JAR Project to a WAR" guide][gs-war] on the
|
|
|
|
spring.io website.
|
|
|
|
|
|
|
|
The WAR file can also be executable if you use the Spring Boot build
|
|
|
|
tools. In that case the embedded container classes (to launch Tomcat
|
|
|
|
for instance) have to be added to the WAR in a `lib-provided`
|
|
|
|
directory. The tools will take care of that as long as the
|
|
|
|
dependencies are marked as "provided" in Maven or Gradle. Here's a
|
|
|
|
Maven example
|
|
|
|
[in the Boot Samples](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-traditional/pom.xml).
|
|
|
|
|
|
|
|
[gs-war]: http://spring.io/guides/gs/convert-jar-to-war
|
|
|
|
|
|
|
|
## 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`.
|
|
|
|
|
|
|
|
TODO: add some detail.
|
|
|
|
|
|
|
|
## Discover Built-in Options for External Properties
|
|
|
|
|
|
|
|
Spring Boot binds external properties from `application.properties`
|
|
|
|
(or `.yml`) (and other places) into an application at runtime. There
|
|
|
|
is not (and technically cannot be) an exhaustive list of all supported
|
|
|
|
properties in a single location because contributions can come from
|
|
|
|
additional JAR files on your classpath. There is a sample
|
|
|
|
[`application.yml`](https://github.com/spring-projects/spring-boot/blob/master/docs/application.yml)
|
|
|
|
with a non-exhaustive and possibly inaccurate list of properties
|
|
|
|
supported by Spring Boot vanilla with autoconfiguration. The
|
|
|
|
definitive list comes from searching the source code for
|
|
|
|
`@ConfigurationProperties` and `@Value` annotations, as well as the
|
|
|
|
occasional use of `RelaxedEnvironment`
|
|
|
|
(c.f. [here](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java?source=c#L65)).
|
|
|
|
|
|
|
|
## Set the Active Spring Profiles
|
|
|
|
|
|
|
|
The Spring `Environment` has an API for this, but normally you would
|
|
|
|
set a System profile (`spring.profiles.active`) or an OS environment
|
|
|
|
variable (`SPRING_PROFILES_ACTIVE`). E.g. launch your application with
|
|
|
|
a `-D...` argument (remember to put it before the main class or jar
|
|
|
|
archive):
|
|
|
|
|
|
|
|
```
|
|
|
|
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.
|
|
|
|
|
|
|
|
```properties
|
|
|
|
spring.profiles.active: production
|
|
|
|
```
|
|
|
|
|
|
|
|
A value set this 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.
|
|
|
|
|
|
|
|
## Change the Location of External Properties of an Application
|
|
|
|
|
|
|
|
Properties from different sources are added to the Spring
|
|
|
|
`Environment` in a defined order, and the precedence for resolution is
|
|
|
|
1) commandline, 2) filesystem (current working directory)
|
|
|
|
`application.properties`, 3) classpath `application.properties`. To
|
|
|
|
modify this you can provide System properties (or environment variables)
|
|
|
|
|
|
|
|
* `config.name` (`CONFIG_NAME`), defaults to `application` as the root
|
|
|
|
of the file name
|
|
|
|
* `config.location` (`CONFIG_LOCATION`) is a comma-separated list of
|
|
|
|
files to load. A separate `Environment` property source is set up
|
|
|
|
for each document found, so the priority order is most significant
|
|
|
|
first. Defaults to
|
|
|
|
`file:./application.properties,classpath:application.properties`. If
|
|
|
|
YAML is used then those files are also added to the list by default.
|
|
|
|
|
|
|
|
See `ConfigFileApplicationContextInitializer` for more detail.
|
|
|
|
|
|
|
|
## 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.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
spring:
|
|
|
|
application:
|
|
|
|
name: cruncher
|
|
|
|
datasource:
|
|
|
|
driverClassName: com.mysql.jdbc.Driver
|
|
|
|
url: jdbc:mysql://localhost/test
|
|
|
|
server:
|
|
|
|
port: 9000
|
|
|
|
```
|
|
|
|
|
|
|
|
Create a file called `application.yml` and stick it in the root of
|
|
|
|
your classpath, and also add `snake-yaml` to your classpath (Maven
|
|
|
|
co-ordinates `org.yaml:snake-yaml`). A YAML file is parsed to a Java
|
|
|
|
`Map<String,Object>` (like a JSON object), and Spring Boot flattens
|
|
|
|
the maps so that it is 1-level deep and has period-separated keys, a
|
|
|
|
lot like people are used to with `Properties` files in Java.
|
|
|
|
|
|
|
|
The example YAML above corresponds to an `application.properties` file
|
|
|
|
|
|
|
|
```properties
|
|
|
|
spring.application.name: cruncher
|
|
|
|
spring.datasource.driverClassName: com.mysql.jdbc.Driver
|
|
|
|
spring.datasource.url: jdbc:mysql://localhost/test
|
|
|
|
server.port: 9000
|
|
|
|
```
|
|
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
server:
|
|
|
|
port: 9000
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
spring:
|
|
|
|
profiles: development
|
|
|
|
server:
|
|
|
|
port: 9001
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
spring:
|
|
|
|
profiles: production
|
|
|
|
server:
|
|
|
|
port: 0
|
|
|
|
```
|
|
|
|
|
|
|
|
In this example the default port is 9000, but if the Spring profile
|
|
|
|
"development" is active then the port is 9001, and if "production" is
|
|
|
|
active then it is 0.
|
|
|
|
|
|
|
|
The YAML documents are merged in the order they are encountered (so
|
|
|
|
later values override earlier ones).
|
|
|
|
|
|
|
|
To do the same thing with properties files you can use
|
|
|
|
`application-${profile}.properties` to specify profile-specific
|
|
|
|
values.
|
|
|
|
|