Documentation

pull/9/head
Phillip Webb 11 years ago
parent 5a7236625b
commit e1c6860a41

@ -91,7 +91,7 @@ You can use an `alias` for the Spring Boot command line tool:
$ alias spring="java -jar ~/.m2/repository/org/springframework/boot/spring-cli/0.5.0.BUILD-SNAPSHOT/spring-cli-0.5.0.BUILD-SNAPSHOT.jar"
_Also see [CONTRIBUTING.md] if you wish to submit pull requests._
_Also see [CONTRIBUTING.md](CONTRIBUTING.md) if you wish to submit pull requests._
## Spring Boot Modules
There are a number of modules in Spring Boot. Here are the important ones:
@ -144,20 +144,20 @@ can also watch files, automatically recompiling and restarting when they change.
### spring-boot-actuator
The Actuator uses auto-configuration to decorate your application with features that
make it instantly deployable and supportable in production. For instance if you are
writing a JSON web service then it will provide a server, security, logging, externalized
configuration, management endpoints, an audit abstraction, and more. If you want to
switch off the built in features, or extend or replace them, it makes that really easy as
well.
Spring Boot Actuator provides additional auto-configuration to decorate your application
with features that make it instantly deployable and supportable in production. For
instance if you are writing a JSON web service then it will provide a server, security,
logging, externalized configuration, management endpoints, an audit abstraction, and
more. If you want to switch off the built in features, or extend or replace them, it
makes that really easy as well.
_See [spring-boot-actuator/README.md](spring-boot-actuator/README.md)._
### spring-boot-loader
Loader provides the secret sauce that allows you to build a single jar file that can be
launched using `java -jar`. Generally you will not need to use `spring-boot-loader`
directly but instead work with the
Spring Boot Loader provides the secret sauce that allows you to build a single jar file
that can be launched using `java -jar`. Generally you will not need to use
`spring-boot-loader` directly but instead work with the
[Gradle](spring-boot-gradle-plugin/README.md) or
[Maven](spring-boot-maven-plugin/README.md) plugin.

@ -1,4 +1,4 @@
# Spring Boot Actuator
# Spring Boot - Actuator
The aim of this project is minimum fuss for getting applications up
and running in production, and in other environments. There is a

@ -37,12 +37,6 @@ have picked a container implementation (by including either Tomcat or
Jetty on the classpath), but then the API is the same. TODO: finish
this.
## Logging
Spring Actuator uses SLF4J for logging, but leaves the implementation
open. The Starter projects and the Actuator use logback logging by
default because it has the richest feature set.
## Info Endpoint
By default the Actuator adds an `/info` endpoint to the main server.

@ -1 +1 @@
# Spring AutoConfigure
# Spring Boot - AutoConfigure

@ -1 +1 @@
# Spring CLI
# Spring Boot - CLI

@ -0,0 +1,5 @@
# Spring Launcher
A very thin Java main for executable JAR and WAR
archives. `JarLauncher` and `WarLauncher` know how to access classpath
resources and dependencies in nested jar files.

@ -1,4 +1,4 @@
# Spring Launcher
# Spring Boot - Loader
A very thin Java main for executable JAR and WAR
archives. `JarLauncher` and `WarLauncher` know how to access classpath

@ -1,4 +1,4 @@
# Spring Package Maven Plugin
# Spring Boot - Maven Plugin
A maven plugin for building executable JAR and WAR files. To use it,
configure your project to build a JAR or WAR (as appropriate) in the

@ -0,0 +1,2 @@
# Spring Boot - Samples

@ -1,4 +1,4 @@
# Spring Starters
# Spring Boot - Starters
Aggregated dependencies for starter projects with an opinionated
choice of Spring and related useful technologies.

@ -1,5 +1,5 @@
# Spring Boot
Spring Boot provides the central features for the other modules in the project. It is
# Spring Boot - Core
This module provides the core features for the other modules in the project. It is
relatively unopinionated and it has minimal required dependencies which makes it usable
as a stand-alone library for anyone whose tastes diverge from ours.
@ -10,7 +10,7 @@ to the static `SpringApplication.run` method:
```java
public static void main(String[] args) {
SpringApplication.run(SpringConfiguration.class, args);
SpringApplication.run(MySpringConfiguration.class, args);
}
```
@ -38,7 +38,7 @@ instance and customize it. For example, to turn off the banner you would write:
```java
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SpringConfiguration.class);
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setShowBanner(false);
app.run(args);
}
@ -52,8 +52,12 @@ should be scanned.
See the `SpringApplication` Javadoc for a complete list of the configuration options
### Accessing command line properties
By default `SpringApplication` will expose any command line arguments as Spring
Properties. This allows you to easily access arguments by injecting them as `@Values`
By default `SpringApplication` will convert any command line option arguments (starting
with '--', e.g. `--server.port=9000`) to a `PropertySource` and add it to the Spring
`Environment` with highest priority (taking precedence and overriding values from other
sources). Properties in the `Environment` (including System properties and OS environment
variables) can always be injected into Spring components using `@Value` with
placeholders, e.g.
```java
import org.springframework.stereotype.*
@ -70,14 +74,11 @@ public class MyBean {
}
```
You can also use the special `--spring.profiles.active` argument to enable specific
Spring profiles from the command line.
### CommandLineRunner beans
If you wan't access to the raw command line argument, or you need to run some specific
If you want access to the raw command line argument, or you need to run some specific
code once the `SpringApplication` has started you can implement the `CommandLineRunner`
interface. The `run(String... args)` method will be called on all spring beans
implementing the interface.
implementing this interface.
```java
import org.springframework.boot.*
@ -106,6 +107,66 @@ can be used.
In addition, beans may implement the `org.springframework.boot.ExitCodeGenerator`
interface if they with to return a specific exit code when the application ends.
### Externalized Configuration
A `SpringApplication` will load properties from `application.properties` in the root of
your classpath and add them to the Spring `Environment`. The actual search path for the
files is:
1. classpath root
2. current directory
3. classpath `/config` package
4. `/config` subdir of the current directory.
The list is ordered by decreasing precedence (so properties can be overridden by others
with the same name defined in later locations). In addition, profile specific properties
can also be defined using the naming convention `application-{profile}.properties`
(properties from these files override the default ones).
The values in `application.properties` are filtered through the existing `Environment`
when they are used so you can refer back to previously defined values (e.g. from System
properties).
```
app.name: MyApp
app.description: ${app.name} is a Spring Boot application
```
If you don't like `application.properties` as the configuration file name you can
switch to another by specifying `spring.config.name` environment property. You can also
refer to an explicit location using the `spring.config.location` environment property.
$ java -jar myproject.jar --spring.config.name=myproject
_NOTE: You can also use '.yaml' files as an alternative to '.properties' (see
[below](#using-yaml-instead-of-properties))_
### Setting the Default Spring Profile
Spring Profiles are a way to segregate parts of the application configuration and make it
only available in certain environments. Any `@Component` that is marked with `@Profile`
will only be loaded in the profile specified by the latter annotation.
A `SpringApplication` takes this a stage further, in that you can use a
`spring.active.profiles` `Environment` property to specify which profiles are active.
You can specify the property in any of the usual ways, for example you could include
it in your `application.properties`:
```
spring.active.profiles=dev,hsqldb
```
or specify on the command line using the switch `--spring.profiles.active=dev,hsqldb`.
### Application Context Initializers
Spring provides a convenient `ApplicationContextInitializer` interface that can be used
to customize an `ApplicationContext` before it is used. If you need to use an initializer
with your `SpringApplication` you can use the `addInitializers` method.
You can also specify initializers by setting comma-delimited list of class names to the
`Environment` property `context.initializer.classes` or by using Spring's
`SpringFactoriesLoader` mechanism.
## Embedded Servlet Container Support
Spring Boot introduces a new type of Spring `ApplicationContext` that can be used to
start an embedded servlet container. The `EmbeddedWebApplicationContext` is a special
@ -116,7 +177,7 @@ type of `WebApplicationContext` that starts the container by searching for a sin
One advantage of using a Spring bean to define the embedded container is that you can use
all the standard Spring concepts. For example, it becomes trivial to define a Tomcat
server that sets its port from an injected `@Value`:
server that sets its port from an injected `@Value`.
```java
@Configuration
@ -136,11 +197,10 @@ public class MyConfiguration {
### Customizing Servlet Containers
Both the Tomcat and Jetty factories extend from the base
`AbstractEmbeddedServletContainerFactory` class. This provides a uniform way
to configure your container regardless of which implementation you actually
choose.
to configure both containers.
Settings that you traditionally configure in a `web.xml` or via an implementation
specific configuration file can now be performed programmatically. For example:
Settings that you would traditionally configure in a `web.xml` or via an implementation
specific configuration file can now be performed programmatically.
```java
@Bean
@ -154,7 +214,7 @@ public EmbeddedServletContainerFactory servletContainer() {
```
In addition, you can also add `ServletContextInitializer` implementations which allow
you to customize the `javax.servlet.ServletContext` in the same way as any Servlet 3
you to customize the `javax.servlet.ServletContext` in the same way as any Servlet 3.0
environment.
### Servlets and Filters
@ -168,11 +228,246 @@ If convention based mapping is not flexible enough you can use the
can also register items directly if your bean implements the `ServletContextInitializer`
interface.
## External Configuration
FIXME include loadcations that SpringApplication hits
fact you can conf SpringApplication
and propery bindings
## Using YAML instead of Properties
[YAML](http://yaml.org) is a superset of JSON, and as such is a very convenient format
for specifying hierarchical configuration data. The `SpringApplication` class will
automatically support YAML as an alternative to properties whenever you have the
[SnakeYAML](http://code.google.com/p/snakeyaml/) library on your classpath.
### Loading YAML
Spring Boot provides two convenient classes that can be used to load YAML documents. The
`YamlPropertiesFactoryBean` will load YAML as `Properties` and the `YamlMapFactoryBean`
will load YAML as a `Map`.
For example, the following YAML document:
```yaml
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
```
Would be transformed into these properties:
```
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
```
YAML lists are represented as comma-separated values (useful for simple String values)
and also as property keys with `[index]` dereferencers, for example this YAML:
```yaml
servers:
- dev.bar.com
- foo.bar.com
```
Would be transformed into these properties:
```
servers=dev.bar.com,foo.bar.com
servers[0]=dev.bar.com
servers[1]=foo.bar.com
```
### Exposing YAML as properties in the Spring Environment.
The `YamlPropertySourceLoader` class can be used to expose YAML as a `PropertySource`
in the Spring `Environment`. This allows you to the familiar `@Value` with placeholders
syntax to access YAML properties.
You can also specify multiple profile-specific YAML document in a single file by
by using a `spring.profiles` key to indicate when the document applies. For example:
```
server:
address: 192.168.1.100
---
spring:
profiles: production
server:
address: 192.168.1.120
```
## Typesafe Configuration Properties
Use the `@Value("${property}")` annotation to inject configuration properties can
sometimes be cumbersome, especially if you are working with multiple properties or
your data is hierarchical in nature. Spring Boot provides an alternative method
of working with properties that allows strongly typed beans to govern and validate
the configuration of your application. For example:
```java
@Component
@ConfigurationProperties(name="connection")
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
```
When the `@EnableConfigurationProperties` annotation is applied to your `@Configuration`,
any beans annotated with `@ConfigurationProperties` will automatically be configured
from the `Environment` properties. This style of configuration works particularly well
with the `SpringApplication` external YAML configuration:
```yaml
# application.yml
connection:
username: admin
remoteAddress: 192.168.1.1
# additional configuration as required
```
To work with `@ConfigurationProperties` beans you can just inject them in the same way
as any other bean.
```java
@Service
public class MyService {
@Autowired
private ConnectionSettings connection;
//...
@PostConstruct
public void openConnection() {
Server server = new Server();
this.connection.configure(server);
}
}
```
It is also possible to shortcut the registration of `@ConfigurationProperties` bean
definitions by simply listing the properties classes directly in the
`@EnableConfigurationProperties` annotation:
```java
@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
public class MyConfiguration {
}
```
### Relaxed binding
Spring Boot uses some relaxed rules for binding `Environment` properties to
`@ConfigurationProperties` beans, so there doesn't need to be an exact match between
the `Environment` property name and the bean property name. Common examples where this
is useful include underscore separated (e.g. `context_path` binds to `contextPath`), and
capitalized (e.g. `PORT` binds to `port`) environment properties.
Spring will attempt to coerce the external application properties to the right type when
it binds to the `@ConfigurationProperties` beans. If you need custom type conversion you
can provide a `ConversionService` bean (with bean id `conversionService`) or custom
property editors (via a `CustomEditorConfigurer` bean).
### @ConfigurationProperties Validation
Spring Boot will attempt to validate external configuration, by default using JSR-303
(if it is on the classpath). You can simply add JSR-303 `javax.valididation` constraint
annotations to your `@ConfigurationProperties` class:
```java
@Component
@ConfigurationProperties(name="connection")
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// ... getters and setters
}
```
## ApplicationContextInitializers
You can also add a custom Spring `Validator` by creating a bean definition called
`configurationPropertiesValidator`.
### Using Project Lombok
You can safely use [Project Lombok](http://projectlombok.org) to generate getters and
setters for your `@ConfigurationProperties`. Refer to the documentation on the Lombok
for how to enable it in your compiler or IDE.
### External EmbeddedServletContainerFactory configuration
Spring Boot includes a `@ConfigurationProperties` annotated class called
`ServerProperties` that can be used to configure the `EmbeddedServletContainerFactory`.
When registered as a bean, the `ServerProperties` can be used to specify:
* The port that the application listens on for its endpoints
(`server.port` defaults to `8080`)
* The address that the application endpoints are available on
(`server.address` defaults to all local addresses, making it available to connections
from all clients).
* The context root of the application endpoints (`server.context_path`
defaults to '/')
If you are using Tomcat as you embedded container then, in addition to the
generic `ServerProperties`, you can also bind `server.tomcat.*` properties
to specify:
* The Tomcat access log pattern (`server.tomcat.accessLogPattern`)
* The remote IP and protocol headers (`server.tomcat.protocolHeader`,
`server.tomcat.remoteIpHeader`)
* The Tomcat `base directory` (`server.tomcat.basedir`)
## Customizing Logging
Spring Boot uses [Commons Logging](commons.apache.org/logging/) for all internal logging,
but leaves the underlying log implementation open. Default configurations are provided for
[Java Util Logging](http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html),
[Log4J](http://logging.apache.org/log4j/) and [Logback](http://logback.qos.ch/).
In each case there is console output and file output (rotating, 10MB file size).
The various logging systems can be activated by including the appropriate libraries on
the classpath, and further customized by supported by providing a suitable configuration
file in the root of the classpath, or in a location specified by the Spring `Environment`
property `logging.config`.
Depending on your logging system, the following files will be loaded:
|Logging System|Customization |
|--------------|-------------------------------|
|Logback | logback.xml |
|Log4j | log4j.properties or log4j.xml |
|JDK | logging.properties |
To help with the customization some other properties are transferred from the Spring
`Environment` to System properties:
|Environment |System Property |Comments |
|-------------|----------------|---------------------------------------------------------------------------|
|logging.file |LOG_FILE | Used in default log configuration if defined |
|logging.path |LOG_PATH | Used in default log configuration if defined |
|PID |PID | The current process ID is discovered if possible and not already provided |
All the logging systems supported can consult System properties when parsing their
configuration files. See the default configurations in `spring-boot.jar` for examples.
## Cloud Foundry Support
When a `SpringApplication` is deployed to [Cloud Foundry](http://www.cloudfoundry.com/)
appropriate meta-data will be exposed as `Environemnt` properties. All Cloud Foundry
properties are prefixed `vcap.` You can use vcap properties to access application
information (such as the public URL of the application) and service information (such
as database credentials). See `ApplicationContextInitializer` Javdoc for complete details.
## Further Reading
For more information about any of the classes or interfaces discussed in the document
please refer to the extensive project Javadoc. If looking to reduce the amount of
configuration required for your application you should consider
[spring-boot-autoconfigure](../spring-boot-autoconfigure/README.md). For operational
concerns see [spring-boot-actuator](../spring-boot-actuator/README.md). For details on
how to package your application into a single executable JAR file take a look at
[spring-boot-loader](../spring-boot-loader/README.md).

@ -1,262 +0,0 @@
# Spring Bootstrap Feature Guide
Here are some (most, hopefully all) the features of Spring Bootstrap
with some commentary to help you start using them.
## Commandline Arguments
Commandline arguments are passed on to any `CommandLineRunner` beans
found in the application. Option arguments (starting with `--`,
e.g. `--server.port=9000`) are converted to a `PropertySource` and
added to the Spring `Environment` with first priority (they always
take precedence and override values from other sources). Properties
in the `Environment` (including System properties and OS environment
variables) can always be injected into Spring components using
`@Value` with placeholders, e.g.
@Component
public class MyService {
@Value("${app.message:Hello World}")
private String message;
...
}
The default value comes after the first colon (":").
## Externalized Configuration
In addition to command line option arguments, Spring Bootstrap will
pick up a file called `application.properties` in the root of your
classpath (if there is one) and add those properties to the Spring
`Environment`. The search path for `application.properties` is
actually, 1) root or classpath, 2) current directory, 3) `/config`
package in classpath, 4) `/config` subdir of current directory. The
list is ordered by decreasing precedence (so properties can be
overridden by others with the same name defined in later locations).
The values in `application.properties` are filtered through the
existing `Environment` when they are used so you can refer back to
previously defined values (e.g. from System properties), e.g.
app.name: MyApp
app.description: ${app.name} is a Cool New App
Spring Bootstrap also binds the properties to any bean in your
application context whose type is `@ConfigurationProperties`. The
Actuator provides some of those beans out of the box, so you can
easily customize server and management properties (ports etc.),
endpoint locations and logging. See below for more detail, or inspect
the `*Properties` types in the Actuator jar.
## Setting the Default Spring Profile
Spring Profiles are a way to segregate parts of the application
configuration and make it only available in certain environments. Any
`@Component` that is marked with `@Profile` will only be loaded in the
profile specified by the latter annotation.
Spring Bootstap takes it a stage further. If you include in your
`application.properties` a value for a property named
`spring.active.profiles` then those profiles will be active by
default. E.g.
spring.active.profiles: dev,hsqldb
## Profile-dependent configuration
Spring Bootstrap loads additional properties files if there are active
profiles using a naming convention `application-{profile}.properties`.
Property values from those files override trhe default ones.
## Custom Typesafe Externalized Configuration
If you want a strongly typed bean (or beans) to govern and validate
the configuration of your application beyond the built in properties,
all you need to do is create a `@ConfigurationProperties` class, e.g.
@ConfigurationProperties(name="my")
public class MyProperties {
}
and declare one either explicitly (with `@Bean`) or implicitly by
adding
@EnableConfigurationProperties(MyProperties.class)
to one of your `@Configuration` (or `@Component`) classes. Then you can
@Autowired
private MyProperties configuration = new MyProperties();
in any of your component classes to grab that configuration and use it.
Spring Bootstrap uses some relaxed rules for binding `Environment`
properties to `@ConfigurationProperties` beans, so there doesn't need
to be an exact match between the `Environment` property name and the
bean property name. Common examples where this is useful include
underscore separated (e.g. `context_path` binds to `contextPath`), and
capitalized (e.g. `PORT` binds to `port`) environment properties.
Spring will attempt to coerce the external application properties to
the right type when it binds to the `@ConfigurationProperties` beans.
If you need custom type conversion you can provide a
`ConversionService` bean (with bean id `conversionService`) or custom
property editors (via a `CustomEditorConfigurer` bean).
Spring will also validate the external configuration, by default using
JSR-303 if it is on the classpath. So you can add annotations from
that specification (or its implementations) to your custom properties,
e.g.
@ConfigurationProperties(name="my")
public class MyProperties {
@NotNull
private String name;
// .. getters and setters
}
You can also add a custom Spring `Validator` by creating a bean
definition called `configurationPropertiesValidator`.
## Using Project Lombok
You can safely use [Project Lombok](http://projectlombok.org) to
generate getters and setters for your `@ConfigurationProperties`.
Refer to the documentation on the Lombok for how to enable it in your
compiler or IDE.
## Using YAML instead of Properties
YAML is a superset of JSON, and as such is a very convenient format
for specifying hierarchical configuration data, such as that supported
by Spring Actuator. If you prefer to use
[YAML](http://yaml.org) instead of Properties files you just need to
include a file called `application.yml` in the root of your classpath
You can if you like add profile specific YAML files
(`application-${profile}.yml`), but a nicer alternative is to use YAML
documents inside `application.yml`, with profile-specific documents
containing a `spring.profiles` key. For example
server:
port: 8080
management:
port: 8080
address: 0.0.0.0
---
spring:
profiles: prod
management:
port: 8081
address: 10.2.68.12
## Customizing the location of the External Configuration
If you don't like `application.properties` or `application.yml` as the
configuration file location you can switch to another location by
specifying the `spring.config.name` (default `application`) or the
`spring.config.location` as environment properties, e.g. if launching
a jar which wraps `SpringApplication`:
$ java -jar myproject.jar --spring.config.name=myproject
## Providing Defaults for Externalized Configuration
For `@ConfigurationProperties` beans that are provided by the
framework itself you can always change the values that are bound to it
by changing `application.properties`. But it is sometimes also useful
to change the default values imperatively in Java, so get more control
over the process. You can do this by declaring a bean of the same
type in your application context, e.g. for the server properties:
@Bean
public ServerProperties serverProperties() {
ServerProperties server = new ServerProperties();
server.setPort(8888);
return server;
}
## Server Configuration
The `ServerProperties` are bound to application properties, and
can be used to specify
* The port that the application listens on for the its endpoints
(`server.port` defaults to 8080)
* The address that the application endpoints are available on
(`server.address` defaults to all local addresses, making it available to connections
from all clients).
* The context root of the application endpoints (`server.context_path`
defaults to "/")
## Tomcat Container Configuration
If you want to use Tomcat as an embedded container include at least
`org.apache.tomcat.embed:tomcat-embed-core` and one of the
`org.apache.tomcat.embed:tomcat-embed-logging-*` libraries (depending
on the logging system you are using). Then, in addition to the
generic `ServerProperties`, you can also bind `server.tomcat.*`
properties in the application properties (see
`ServerProperties.Tomcat`).
* To enable the Tomcat access log valve (very common in production environments)
More fine-grained control of the Tomcat container is available if you
need it. Instead of letting Spring Actuator create the container for
you, just create a bean of type
`TomcatEmbeddedServletContainerFactory` and override one of its
methods, or inject some customizations, e.g.
@Configuration
public class MyContainerConfiguration {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setConnector(new Connector("AJP/1.3"));
}
}
(the default connector uses the `Http11NioProtocol` so the example if
overriding that behaviour).
## Customizing Logging
Spring Bootstrap uses Commons Logging for logging, but leaves the
implementation open. A default configuration file is provided for
logback, and also for log4j and JDK logging. In each case there is
console output and file output (rotating, 10MB file size).
The various logging systems can be activated by including the right
libraries on the classpath, and further customized by providing a
native configuration file in the root of the classpath, or in a
location specified by the Spring `Environment` property
`logging.config`.
|Logger|Activation |Customization |
|---|---|---|
|JDK |slf4j-jdk14 | logging.properties |
|Logback |logback | logback.xml |
|Log4j |slfj4-log4j12, log4j | log4j.properties or log4j.xml |
To help with the customization some other properties are transferred
from the Spring `Environment` to System properties:
|Environment|System Property |Comments |
|---|---|---|
|logging.file |LOG_FILE | Used in default log configuration if defined |
|logging.path |LOG_PATH | Used in default log configuration if defined |
|PID |PID | The current process ID is discovered if possible and not already provided |
All the logging systems supported can consult System properties when
parsing their configuration files. See the default configurations in
`spring-boot.jar` for examples.
## Application Context Initializers
To add additional application context initializers to the bootstrap
startup process, add a comma-delimited list of class names to the
`Environment` property `context.initializer.classes` (can be specified
via `application.properties`).
Loading…
Cancel
Save