Spring Boot introduced the concept of automatic configuration of the components of a Spring Application. As soon as you
add a Spring Boot library to your classpath, Spring Boot automatically detects the library at startup time and wires up
the components in the library into your Spring ApplicationContext
.
Spring Boot follows a convention over configuration approach. For example, if you include the
spring-boot-starter-jdbc
library in your project, Spring Boot will automatically create instances of DataSource
and
JdbcTemplate
. By default, this will be an embedded H2 database. You can customize this by providing configuration
properties such as a database URL into the ApplicationContext
. Spring Boot will then set up a DataSource
and a
JdbcTemplate
that connect to the given database.
Or you create the beans for DataSource
or JdbcTemplate
yourself in one of your @Configuration
classes. Spring Boot
detects that there are already beans in the ApplicationContext
and does not create its default beans.
Girders 6 also provides auto-configuration support for most of its functionality.
For your application code, we recommend using Java and Annotation-based configuration with Constructor Injection. Beans
can be defined in an @Configuration
class or you can use component-scanning with component annotations
(@Service
, @Repository
, @RestController
, …) for the beans of your application.
Our recommendation for Girders 6 applications is to use the auto-configuration features of Spring Boot and Girders
as much as possible and provide the remaining configuration for your application in @Configuration
classes. We
recommend creating multiple @Configuration
classes to modularize the configuration. Component-scanning can be
used, but we recommend limiting component-scanning to small sub-packages. For the configuration of beans, we recommend
using Constructor Injection rather than field injections with @Autowired
annotations.
You could of course also implement your own AutoConfiguration
modules in your application code. For most applications
though, this will be an overkill. Auto-configuration only really makes sense for frameworks that you compose on a
case-by-case basis into different applications. So definitely something for products that need to be highly
customizable, but not for most of the other applications that we write at Netcetera.
We recommend using one application.yml
configuration file for the application and consuming the configuration in
your components and configuration classes with
@ConfigurationProperties
classes. ConfigurationProperties allow to
define structured interfaces for configuration properties which are strongly typed.
The application.yml
is baked into the application artifact (JAR or WAR file) and shipped and deployed together with
with the application code. It must therefore only contain configuration properties that are not environment-specific
or sensible defaults for properties that are environment-specific. In Girders, we recommend following the
12 factor app configuration approach. With this
pattern, you only put default configuration into the application bundle itself. All the configuration that is
environment-specific is injected into the application from the outside. You might still managed this configuration
in configuration files similar to application.yml
, but you would not bundle them in your application anymore
and deploy them separately.
Here is an example for an application.yml
configuration file:
# Application Basics
spring:
application.name: ${project.artifactId}
main.banner-mode: 'off'
info.app:
project: "your-project-id"
name: ${project.artifactId}
version: ${project.version}
girders.version: ${girders.version}
spring-boot.version: ${spring-boot.version}
# Rate Limiting (Default that is probably overwritten by environment-specific configuration)
showcase.rate-limit.global-rate-limit-spec: 1000/m
# Mail (This is environment-specific and does not belong here)
# girders.mail.host: mail.netcetera.com
Spring Boot provides a variety of different ways for injecting environment-specific configuration. Which one you want to use in your application depends a lot on the infrastructure that you have, the deployment model etc. Here are our recommendations:
Spring Boot provides the possibility to provide individual configuration values through the command-line when starting up the application or through environment properties of the OS.
java -jar -Dgirders.mail.host=mail.netcetera.com app.war
You can use this mechanism to provide configuration properties or overwrite configuration properties that are already
defined in application.yml
.
This mechanism works very well, as long as you have a relatively small number of environment-specific configuration values to inject. In cases where you have more values, you can also provide a pointer to an environment-specific configuration file. This file should not be packaged together with the application, but separately and deployed independently of the application.
java -jar -Dspring.config.addition-location=file:///var/www/foo/conf/application-prod.yml app.war
If you have a web application, you can also use the web application context or container context to provide
environment-specific configuration properties to the applications. Obviously, the context.xml
file should not be
packaged into the WAR file itself.
<?xml version='1.0' encoding='utf-8'?>
<Context contextPath="/demo-showcase" docBase="demo-showcase">
<Parameter name="girders.mail.host" value="mail.netcetera.com"/>
</Context>
Configuration parameters from the web application context are injected into the Spring configuration properties. So your application does not even realize that the configuration is coming from a different source.
If you have configuration properties such as database connections or caches that are already configured in the
application server and exposed through JNDI, you can also use these entries for the application configuration.
Spring automatically picks up entries in java:comp/env
.
Girders also supports obfuscation and encryption of configuration properties. More information can be found in the documentation of the Cryptography features.
For more advanced configuration options, please check out the Advanced Configuration chapter.