Spring Boot : Configuring properties

Spring Boot provides a very neat way to load properties for an application. From the previous post we know that by default spring looks for application.properties/application.yml file in the root and loads the properties from there. Suppose we have a application.properties with following values:


project.name=Spring boot
project.database=Mysql
project.database.maxConnections=10

These entries can also be setted in yaml format as :


project:
      name : Spring boot
      database : Mysql
             maxConnections : 10

This yaml as a property file will work because the snaleyml class is in the classpath. Yaml files are more concise. In .properties file you would normally have a common root which is repeated over multiple lines. Its your choice which type to use. Here we would be using application.properties

Lets write our Application.java using these properties file:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;

@SpringBootApplication
@EnableConfigurationProperties
public class Application {

@Value("${project.database.maxConnections}")
private int maxNumberOfConnections;

@Value("${project.name}")
void setProjectName(String projectName) {
System.out.println("setting project name:::::::::::: " + projectName);
System.out.println("maxNumberOfConnections:::::::::::: " + maxNumberOfConnections);
}

@Autowired
void getFromEnvironment(Environment env) {
System.out.println(
"setting environment:::::::::::: " + env.getProperty("project.name"));
}
@Autowired
void setProjectProperties(ProjectProperties pp) {
System.out.println("setProjectProperties.name:::::::::::: " + pp.getName());
System.out.println("setProjectProperties.database:::::::::::: " + pp.getDatabase());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

 

@EnableConfigurationProperties tells spring that we want to map properties to a POJO.

First way is the traditional way of loading up the properties. The conversion to int is automatically done by spring.

Second way is telling spring to inject properties into a method.

Third way to inject the Environment object (its a global object that spring makes available for you) into your method. You can get your required object from this.

Fourth way is to inject an custom configuration object and get from those. Here we have created a custom class ProjectProperties


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties("project")
public class ProjectProperties {

private String name;
private String database;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
}

Its a Component with @ConfigurationProperties(“project”), that tells spring to get and map properties string with “project” key. The names must be the same as that in the property file. This object is created with the values and then injected into the method previously .

Lets build the project by

mvn clean package

and run by

java -jar target/spring-boot-loading-properties-0.0.1-SNAPSHOT.jar

spring-boot-property1

You can override this properties from command line while running the application like:


java -Dproject.name="Spring boot from command line" -jar target/spring-boot-loading-properties-0.0.1-SNAPSHOT.jar

spring-boot-property2

You can also override the properties by creating a application.properties file in the same folder as the jar and run from there. Creating application.properties in target folder:


project.name=Spring boot from external application.properties file

Note you have to be in the target folder or whereever your jar is kept in order for spring to pickup this. Run following:


java -jar spring-boot-loading-properties-0.0.1-SNAPSHOT.jar

spring-boot-property3

You can use env variables also to override. Like say using export (on ubuntu/mac)


export PROJECT_NAME="SPRING BOOT FROM ENV"

java -jar spring-boot-loading-properties-0.0.1-SNAPSHOT.jar

spring-boot-property4

As you can see we use capital letters. Spring does this via relax binding. So

person.firstName = person.first-name=PERSON_FIRST_NAME

Real applications usually run in different environments and need environment specific properties / property files. In Spring Boot you do this by following the naming schema application-<environment>.properties for your property files like application-dev.properties or application-prod.properties. You can select whatever string you want for environment. Spring decides which file to use by looking for the environment variable spring.profiles.active.
Lets create these files with different values application-dev.properties:


project.name=Spring boot dev
project.database=Mysql
project.database.maxConnections=10

application-prod.properties:


project.name=Spring boot prod
project.database=Mysql
project.database.maxConnections=10

Running :


java -jar  -Dspring.profiles.active=dev target/spring-boot-loading-properties-profiles-0.0.1-SNAPSHOT.jar

spring-boot-property5

Loading prod one


java -jar  -Dspring.profiles.active=prod target/spring-boot-loading-properties-profiles-0.0.1-SNAPSHOT.jar

spring-boot-property6

You can also set this variable in our IDE’s so that when you are running locally it takes always the dev one. For servers you can set environment variable and spring will take that. For example:


export SPRING_PROFILES_ACTIVE=prod

java -jar target/spring-boot-loading-properties-profiles-0.0.1-SNAPSHOT.jar

You must have a spring.profiles.active set somewhere else it will throw error.

 

Advertisements
%d bloggers like this: