If you are using some configuration parameters in your application then it is better to externalize your configuration rather than hard coding values. In Spring Boot one of the way to externalize your configuration is to use properties files or YAML files. In this post we’ll see how to use properties file in Spring Boot and how to read property values from properties file.
Spring Boot application.properties file
In Spring Boot, SpringApplication automatically loads properties from application.properties files and adds them to the Spring Environment. You should save application.properties file in one of the following locations.
- A /config subdirectory of the current directory
- The current directory
- A classpath /config package
- The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
Note that you can also use YAML ('.yml') files as an alternative to '.properties'.
Creating application.properties file
Create application.properties file inside src/main/resources directory as the properties file should be in classpath.
Add some key-value pairs to application.properties file.
springboot.app.name=SpringBootProject springboot.welcome.message=Welcome User
Using YAML file
You can also create an application.yml file instead of application.properties at the same location. YAML is a superset of JSON, it is a convenient format for specifying hierarchical configuration data.
Sample application.yml file
springboot: app: name:SpringBootProject welcome: message:Welcome User
Switching to another file name
If you want to name your configuration file as something other than application.properties you can do that by specifying a spring.config.name environment property.
java -jar SpringBootProject.jar --spring.config.name=myprops
You can also refer to an explicit location by using the spring.config.location environment property
java -jar SpringBootProject.jar --spring.config.location=classpath:/default.properties, classpath:/override.properties
Injecting configuration values using @Value annotation
Once you have your properties file ready you can use it in your Spring beans. One of the way to inject a property value from the properties is to use @Value annotation. Using @Value annotation you can read an environment variable or a system variable.
Here is a class where @Value annotation is used on the fields to inject property values by using the key of the properties.
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class WelcomeConfiguration { @Value("${springboot.app.name}") private String name; @Value("${springboot.welcome.message}") private String message; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
You can test it using the following application class.
import org.netjs.SpringBootApp.controller.WelcomeConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootAppApplication implements CommandLineRunner{ @Autowired WelcomeConfiguration config; public static void main(String[] args) { SpringApplication.run(SpringBootAppApplication.class, args); } @Override public void run(String... args) throws Exception { // displaying property values System.out.println("Application Name- " + config.getName()); System.out.println("Welcome Message- " + config.getMessage()); } }Output
Application Name- SpringBootProject Welcome Message- Welcome User
Application configuration using @ConfigurationProperties annotation
Using the @Value("${property}") annotation to inject configuration properties becomes tedious if you have multiple properties or your data is hierarchical in nature. Spring Boot provides a better alternative @ConfigurationProperties annotation to read configuration values from properties file.
To see how to use @ConfigurationProperties to read values from a properties file in Spring Boot application let’s create src/main/resources/application.properties file with values of different data types and also hierarchical in nature.
springboot.app.name=SpringBootProject springboot.app.creator=knpcode springboot.app.active=true springboot.app.pages=4 #List springboot.app.citycodes=US,IN,CN,AU #-- Nested Properties-- springboot.app.inner.strproperty=test #List springboot.app.inner.datalist[0]=list0 springboot.app.inner.datalist[1]=list1 #Map springboot.app.inner.propmap.key1=value1 springboot.app.inner.propmap.key2=value2 springboot.app.inner.propmap.key3=value3
Next is the class annotated with @ConfigurationProperties annotation which is an annotation for externalized configuration and binds some external Properties from a .properties or YAML file.
import java.util.List; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix="springboot.app") public class WelcomeConfiguration { private String name; private String creator; private boolean active; private int pages; private List<String> cityCodes; private final Inner inner = new Inner(); public static class Inner{ private String strProperty; private List<String> dataList; private Map<String, String> propMap; public void setStrProperty(String strProperty) { this.strProperty = strProperty; } //.. getters and setters } public String getName() { return name; } public Inner getInner() { return inner; } //.. getters and setters }
Some points to note here are-
- Using prefix element you can specify the properties that can be bound to the POJO. It can also take care of hierarchical properties (as done for static inner class in the example).
- Property value binding is done in type safe manner. As you can see in the POJO class there are fields of different types String, boolean, int, List, Map all of these fields are bound by converting properties to required types.
- Even if the keys in properties file are in all lower case those are correctly bound to their camel case counterparts in POJO class.
Using the following class you can display the bound properties.
import org.netjs.SpringBootApp.controller.WelcomeConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootAppApplication implements CommandLineRunner{ @Autowired WelcomeConfiguration config; public static void main(String[] args) { SpringApplication.run(SpringBootAppApplication.class, args); } @Override public void run(String... args) throws Exception { // displaying property values System.out.println("Application Name- " + config.getName()); System.out.println("Creator- " + config.getCreator()); System.out.println("Active- " + config.isActive()); System.out.println("Pages- " + config.getPages()); System.out.println("Codes- " + config.getCityCodes()); System.out.println("Strporoperty- " + config.getInner().getStrProperty()); System.out.println("Data List- " + config.getInner().getDataList()); System.out.println("Prop Map- " + config.getInner().getPropMap()); } }Output
Application Name- SpringBootProject Creator- knpcode Active- true Pages- 4 Codes- [US, IN, CN, AU] Strporoperty- test Data List- [list0, list1] Prop Map- {key1=value1, key2=value2, key3=value3}
@ConfigurationProperties Validation
Spring Boot attempts to validate @ConfigurationProperties classes whenever they are annotated with Spring’s @Validated annotation. JSR-303 javax.validation is supported and you can use JSR-303 javax.validation constraint annotations directly on your configuration class.
Add the spring-boot-starter-validation to get a compliant JSR-303 implementation on your classpath.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
Add @Validated annotation and validation constraints on fields.
import java.util.List; import java.util.Map; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @ConfigurationProperties(prefix="springboot.app") @Validated public class WelcomeConfiguration { @NotNull private String name; private String creator; private boolean active; private int pages; @NotEmpty private List<String> cityCodes; //it’s good practice to annotate the nested properties // associated field as @Valid @Valid private final Inner inner = new Inner(); public static class Inner{ @Size(min = 10, max = 20) private String strProperty; private List<String> dataList; private Map<String, String> propMap; //getters and setters } //getters and setters }
Now if citycodes are removed from the application properties file and value for strProperty field is “test” (as per validation length of the value should be in range 10 to 20.) you should get the following error message.
*************************** APPLICATION FAILED TO START *************************** Description: Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'springboot.app' to org.netjs.SpringBootApp.controller.WelcomeConfiguration failed: Property: springboot.app.inner.strProperty Value: test Reason: size must be between 10 and 20 Property: springboot.app.cityCodes Value: [] Reason: must not be empty Action: Update your application's configuration
That's all for the topic Spring Boot Properties File: @ConfigurationProperties Example. If something is missing or you have something to share about the topic please write a comment.
You may also like
- Spring Boot + Spring Data JPA + MySQL + Spring RESTful
- Spring @Scope Annotation
- Exception Handling With Java Lambda Expressions
- Create a Date Object With Values in Java
- Java String replace Method With Examples
- Constructor Chaining in Java
- Generating PDF in Java Using OpenPDF Tutorial
- Avro MapReduce Example
No comments:
Post a Comment