Customizing configuration files

It's one thing to have the ability to create applications quickly and without a huge volume of work, but no less important is the ability to easily customize and override default settings. Spring Boot comes in handy and provides mechanisms that enable configuration management. The simplest way to do that is using configuration files, which are appended to the application fat JAR. Spring Boot automatically detects configuration files whose name start with the application prefix. Supported file types are .properties and .yml. Therefore, we can create configuration files, such as application.properties or application.yml, and even including profile-specific files such as, application-prod.properties or application-dev.yml. Moreover, we can use OS environment variables and command-line arguments to externalize configuration. When using properties or YAML files, they should be placed in one of the following locations:

  • A /config subdirectory of the current application directory
  • The current application directory
  • A classpath /config package (for example, inside your JAR)
  • The classpath root

If you would like to give a specific name to your configuration file, other than application or application-{profile}, you need to provide a spring.config.name environment property during startup. You can also use the spring.config.location property, which contains a comma-separated list of directory locations or file paths:

java -jar sample-spring-boot-web.jar --spring.config.name=example
java -jar sample-spring-boot-web.jar --spring.config.location=classpath:/example.properties

Inside configuration files, we can define two types of properties. First, there is a group of common, predefined Spring Boot properties consumed by the underlying classes mostly from the spring-boot-autoconfigure library. We can also define our own custom configuration properties, which are then injected into the application using the @Value or @ConfigurationProperties annotations.

Let's begin with the predefined properties. The full list of supported by the Spring Boot project is available in their documentation in Appendix A, in the Common application properties section. Most of them are specific to certain Spring modules, such as databases, web servers, security, and some other solutions, but there is also a group of core properties. Personally, I prefer using YAML instead of properties files because it is easily readable by humans, but the decision is yours. Most commonly, I override such properties as application name, which is used for service discovery and distributed configuration management; web server port; logging; or database connection settings. Usually, application.yml file is placed in the src/main/resources directory, which is then located in the JAR root directory after the Maven build. Here's a sample configuration file, which overrides default server port, application name, and logging properties:

server: 
port: ${port:2222}

spring:
application:
name: first-service

logging:
pattern:
console: "%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"
file: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
level:
org.springframework.web: DEBUG
file: app.log

The one really cool thing here is that you don't have to define any other external configuration files, for example, log4j.xml or logback.xml, for logging configuration. In the previous fragment, you can see that I changed the default log level for org.springframework.web to DEBUG and log patterns, and created a log file, app.log, placed in the current application directory. Now, the default application name is first-service and the default HTTP port is 2222.

Our custom configuration settings should also be placed in the same properties or YAML files. Here's a sample application.yml with custom properties:

name: first-service
my:
servers:
- dev.bar.com
- foo.bar.com

A simple property can be injected using the @Value annotation:

@Component
public class CustomBean {

    @Value("${name}")
    private String name;

    // ...
}

There is also the ability to inject more complex configuration properties using the @ConfigurationProperties annotation. The list of values defined in the my.servers property inside the YAML file was injected to the target bean of type java.util.List:

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}

So far, we have managed to create a simple application that does nothing more than start Spring on a web container such as Tomcat or Jetty. In this part of the chapter, I wanted to show you how simple it is to start application development using Spring Boot. Apart from that, I have described how to customize configuration using YAML or properties files. For those people who prefer clicking to typing, I recommend the Spring Initializr website (https://start.spring.io/), where you can generate the project stub based on options you choose. In the simple site view, you can choose build tools (Maven/Gradle), language (Java/Kotlin/Groovy), and Spring Boot version. Then, you should provide all necessary dependencies using the search engine following the Search for dependencies label. I included spring-boot-starter-web, which is just labeled as Web on Spring Initializr as you see in the following screenshot. After clicking on Generate project, the ZIP file with the generated source code gets downloaded onto your computer. You might also be interested in knowing that by clicking Switch to the full version, you are able to see almost all available Spring Boot and Spring Cloud libraries, which can be included in the generated project:

I think that, since we have been going over the basics about building projects using Spring Boot, this is the right time to add some new features to our sample application.