In Spring, you can use @PropertySource
annotation to externalize your
configuration to a properties file. In
this article, we will discuss how to use @@PropertySource
to read a
properties file and display the values
with @Value
and Environment
The @PropertySource
annotation provides a convenient and declarative
mechanism for adding a PropertySource
to
Spring’s Environment. To be used in conjunction with @Configuration classes.
In this example, we are reading database configuration from file config.properties
file and setting these
property values to DataSourceConfig
class using Environment
.
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {
@Autowired
Environment env;
@Override
public void afterPropertiesSet() throws Exception {
setDatabaseConfig();
}
private void setDatabaseConfig() {
DataSourceConfig config = new DataSourceConfig();
config.setDriver(env.getProperty("jdbc.driver"));
config.setUrl(env.getProperty("jdbc.url"));
config.setUsername(env.getProperty("jdbc.username"));
config.setPassword(env.getProperty("jdbc.password"));
System.out.println(config.toString());
}
}
Any ${…} placeholders present in a @PropertySource
resource location will be
resolved against the set of
property sources already registered against the environment.
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/config.properties")
public class ProperySourceDemo implements InitializingBean {
@Autowired
Environment env;
@Override
public void afterPropertiesSet() throws Exception {
setDatabaseConfig();
}
private void setDatabaseConfig() {
DataSourceConfig config = new DataSourceConfig();
config.setDriver(env.getProperty("jdbc.driver"));
config.setUrl(env.getProperty("jdbc.url"));
config.setUsername(env.getProperty("jdbc.username"));
config.setPassword(env.getProperty("jdbc.password"));
System.out.println(config.toString());
}
}
Assuming that "my.placeholder" is present in one of the property sources already registered, e.g. system
properties or environment variables, the placeholder will be resolved to the corresponding value. If not,
then "default/path" will be used as a default. If no default is specified and a property cannot be resolved,
an IllegalArgumentException
will be thrown
Introduces new @PropertySources
to support Java 8 and a better way to include
multiple properties files.
@Configuration
@PropertySources({
@PropertySource("classpath:config.properties"),
@PropertySource("classpath:db.properties")
})
public class AppConfig {
//...
}
Allow @PropertySource
to ignore the not found properties file.
@Configuration
@PropertySource("classpath:missing.properties")
public class AppConfig {
//...
}
If missing.properties
is not found, the system is unable to start and throws
FileNotFoundException
Caused by: java.io.FileNotFoundException:
classpath resource [missiong.properties] cannot be opened because it does not exist
In Spring 4, you can use ignoreResourceNotFound
to ignore the not found
properties file
@Configuration
@PropertySource(value="classpath:missing.properties", ignoreResourceNotFound=true)
public class AppConfig {
//...
}
@PropertySources({
@PropertySource(value = "classpath:missing.properties", ignoreResourceNotFound=true),
@PropertySource("classpath:config.properties")
})
Let's create a simple Spring boot maven project to bootstrap quickly.
In this example, we are reading database configuration from the file config.properties
file and setting these
property values to DataSourceConfig
class.
Create a maven project using Spring Initializr at http://start.spring.io/, which is an online Spring Boot application generator.
Create a packing structure as per the above diagram.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0
<groupId>net.guides.springboot2
<artifactId>spring-propertysource-example
<version>0.0.1-SNAPSHOT
<packaging>jar
<name>spring-propertysource-example
<description>Demo project for Spring Boot
<parent>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter-parent
<version>3.0.4
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8
<project.reporting.outputEncoding>UTF-8
<java.version>17
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter
</dependency>
<dependency>
<groupId>org.springframework.boot
<artifactId>spring-boot-starter-test
<scope>test
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot
<artifactId>spring-boot-maven-plugin
</plugin>
</plugins>
</build>
</project>
Let's create a config.properties
file in classpath and we will use @PropertySource
annotation to read a
properties file and display the values with @Value
and Environment.
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/dev_db
jdbc.username=root
jdbc.password=root
public class DataSourceConfig {
private String driver;
private String url;
private String username;
private String password;
@Override
public String toString() {
return "DataSourceConfig [driver=" + driver + ", url=" + url + ", username=" + username + "]";
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(ProperySourceDemo.class);
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Autowired
Environment env;
@Override
public void afterPropertiesSet() throws Exception {
LOGGER.info(driver);
LOGGER.info(url);
LOGGER.info(password);
LOGGER.info(username);
setDatabaseConfig();
}
private void setDatabaseConfig() {
DataSourceConfig config = new DataSourceConfig();
config.setDriver(env.getProperty("jdbc.driver"));
config.setUrl(env.getProperty("jdbc.url"));
config.setUsername(env.getProperty("jdbc.username"));
config.setPassword(env.getProperty("jdbc.password"));
System.out.println(config.toString());
}
}
This spring boot application has an entry point Java class called Application.java with the public static void main(String[] args) method, which you can run to start the application.
package net.guides.springboot2.springpropertysourceexample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Let's run Application.java
class and observe the console output.
Note that the database configurations are printed at the console using the Environment
class.