Pages

Saturday, April 25, 2020

How To Load Outside Property Files In Spring Boot





1. Introduction


In this tutorial, we'll learn how to load the properties from external loccation that is from outside of jar file. Loading the properties file from an external location can be done in multiple ways but you should decide which one is suitable for your scenario.

Spring Boot 2 Tutorials

How To Load Outside Property Files In Spring Boot


2. Loading from application.properties


By default, Spring boot will load all the properties from the application.properties file which is located at "src/main/resources".


application.properties

[welcome.text=Hello, Welcome to the demo application on Property Loader.
error.message=System is down. Maintainance is going on. Come back after some time.]

Main Boot application

[ConfigurableApplicationContext applicationContext = SpringApplication.run(PropertiesLoaderDemoApplication.class,
args);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
logger.info("loaded locations : "+environment.getPropertySources());
String welcomeNote = environment.getProperty("welcome.text");
logger.info("welcome.text value : " + welcomeNote);]

Output:

[Started PropertiesLoaderDemoApplication in 0.925 seconds (JVM running for 1.262)
loaded locations : [ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}]
welcome.text value : Hello, Welcome to the demo application on Property Loader.]

From the output, We could see the loaded properties file locations. It is clearly saying loaded only from the classpath location application.properties file.

3. Load Using Profiles


Additional to the default one, Spring Boot provides the way to use active profiles to load additional configurations via java command or java programmatically.

Now, Add the new property file named application-error.properties in the classpath and add error codes into the file.

application-error.properties

[error.404=Not Found
error.400=Bad Request
error.403=Forbidden
errro.401=Unauthorized]

Here the profile name is "error". To make profile based properties file, you need to add "-profilename" at the end of the file as application-error.properties.

And also this file must be present in the classpath("src/main/resources").

Profile Name: 

[application-{profile}.properties]

Command to run the jar along with the profile jar:

flag spring.profiles.active will take profiles names comma-separated if you have many.

[java -jar PropertiesLoader-demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=error]

After running the command, you can see in the log what are the files loaded and its location. Here, we can see classpath:/application-error.properties and classpath:/application.properties.

Look at the last line of output, it has pulled the property from a new file for "error.400".

[javaprogramto$ java -jar PropertiesLoader-demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=error
2020-04-25 16:00:08.256  INFO 55969 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : Starting PropertiesLoaderDemoApplication v0.0.1-SNAPSHOT on Venkateshs-MacBook-Pro-2.local with PID 55969 (/Users/venkateshn/Documents/VenkY/blog/workspace/PropertiesLoader/target/PropertiesLoader-demo-0.0.1-SNAPSHOT.jar started by venkateshn in /Users/venkateshn/Documents/VenkY/blog/workspace/PropertiesLoader/target)
2020-04-25 16:00:08.258  INFO 55969 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : The following profiles are active: error
2020-04-25 16:00:08.680  INFO 55969 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : loaded locations : [ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, SimpleCommandLinePropertySource {name='commandLineArgs'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application-error.properties]'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}]
2020-04-25 16:00:08.677  INFO 55969 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : Started PropertiesLoaderDemoApplication in 0.822 seconds (JVM running for 1.173)
2020-04-25 16:00:08.681  INFO 55969 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : errorCode400 : Bad Request
javaprogramto$ ]

Note: If any property is present in two files then it picks the new value from profile properties file because application.properties values are overridden by the application-error.properties.

4. Loading From Command Line Arguments


Another interesting way is to load from command line is most useful when you are running the app as standalone. Once you build the application jar file then we can pass the property files to the java jar command as below.

But whatever values passed from the command line will be overriding all previous values set in the configuration file.

[java -jar PropertiesLoader-demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=error --error.400="Bad Request Again Occured"]

Supplying a new value for "error.400" property via command-line arguments and see the output.

[2020-04-25 16:16:03.263  INFO 56655 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : Started PropertiesLoaderDemoApplication in 0.855 seconds (JVM running for 1.205)
2020-04-25 16:16:03.267  INFO 56655 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : errorCode400 : Bad Request Again Occured]

Hence, command-line arguments will always override all other configurations.

Use "spring.config.additional-location" the parameter to load from outside of the application or jar in the command line.

5. Environment Variables


If java -jar command does not allow any arguments then you have to find out another way. For this spring boot have the power to read from environment variables such as from SPRING_CONFIG_NAME and SPRING_CONFIG_LOCATION.

[export SPRING_CONFIG_NAME=application,applicatio-error
export SPRING_CONFIG_LOCATION=file:///Users/home/config
java -jar demo-app.jar]

But still, application loads the default file and if there is a collision among the files then env specific will take advantage.

6. Loading with @PropertySource Annotation


IF you want to load file other than application.properties and also if any dependency comes with an embedded file that to be loaded then you should use an additional annotation @PropertySource on the @SpringBootApplication annotated class as below.

Created another new file success-codes.properties to load from java class with @PropertySource.

[success.200=Success
success.201=Created
success.202=Accepted
success.203=partial response]

Java Program:

[import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
@PropertySource("classpath:success-codes.properties")
@SpringBootApplication
public class PropertiesLoaderDemoApplication {
private static Logger logger = LoggerFactory.getLogger(PropertiesLoaderDemoApplication.class);
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(PropertiesLoaderDemoApplication.class,
args);
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String successCode200 = environment.getProperty("success.200");
logger.info("successCode200 : "+successCode200);
}
}]

Output:

[2020-04-25 16:37:44.475  INFO 57597 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : successCode200 : Success]


Note: @PropertySource annotated configurations files will be loaded before the default one. So, all these will be overridden by the application.properties file if a collision happens.

Adding now the same "success.200" property in application.properties file and see what value is assigned to it.

[success.200=Great, Perform Next Step]

Output:

[2020-04-25 16:39:14.542  INFO 57658 --- [           main] c.j.p.P.PropertiesLoaderDemoApplication  : successCode200 : Great, Perform Next Step]

Note: I did not tell another point as of now that spring boot will load another folder default that is "config" from classpath and file name is application.properties.

If you have placed an application.properties file in both places then config folder one will take the precedence.

7. Ignoring Properties Files


Sometimes you want to ignore some properties files from the config folder then maven plugin gives the way to do it as following.

By default, maven includes all files from the "src/main/resources" folder. You need to add the following to ignore config-success-properties files.

[<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>**/config-success.properties</exclude>
            </excludes>
        </resource>
    </resources>
</build>]

8. Conclusion


In conclusion, We've seen all possible ways to load the properties file classpath and outside the application or app jar location.


As usual, the complete code is over GitHub and you can download from below links.

[lock]

[View on GitHub ##eye##]

[Download ##file-download##]

[/lock]

Spring Boot - External Properties Files

No comments:

Post a Comment

Please do not add any spam links in the comments section.