Spring @PropertySource Annotation Example

By Arvind Rai, November 22, 2021
This page will walk through Spring @PropertySource annotation example.
1. The @PropertySource annotation is the declarative mechanism for adding PropertySource to the Spring Environment.
2. The @PropertySource annotation is used in conjunction with @Configuration classes.
3. The key/value data of property files loaded by @PropertySource can be read by using @Value and Environment.
4. If a property key exists in more than one property files, the last @PropertySource annotation processed will override any previous key with the same name.
5. The property file path passed in @PropertySource can have ${...} placeholders.

Using @PropertySource

1. Find the code to use @PropertySource annotation.
@PropertySource("classpath:/com/cp/myConfig.properties") 
@Configuration
public class AppConfig {
  ------
} 
2. To load multiple property files, we can use multiple @PropertySource annotation as following.
@PropertySources({ 
  @PropertySource("classpath:/com/cp/myConfig1.properties"),
  @PropertySource("classpath:/com/cp/myConfig2.properties") 
})
@Configuration
public class AppConfig {
  ------
} 
3. Since Java 8, annotations can be repeatable. The @PropertySource annotation is a repeatable annotation.
@PropertySource("classpath:/com/cp/myConfig1.properties")
@PropertySource("classpath:/com/cp/myConfig2.properties") 
@Configuration
public class AppConfig {
  ------
} 
Find the complete example.
AppConfig.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;

@PropertySources({ 
  @PropertySource("classpath:/com/cp/myConfig1.properties"),
  @PropertySource("classpath:/com/cp/myConfig2.properties") 
})
@Configuration
public class AppConfig {
  @Autowired
  Environment env;

  @Bean
  public Country getCountry() {
	Country country = new Country();
	country.setName(env.getProperty("country.name"));
	country.setCapital(env.getProperty("country.capital"));
	return country;
  }

  @Bean
  public City getCity() {
	City city = new City();
	city.setName(env.getProperty("city.name"));
	city.setDm(env.getProperty("city.dm"));
	city.setCountryName(env.getProperty("country.name"));
	return city;
  }
} 
myConfig1.properties
country.name=India
country.capital=New Delhi 
myConfig2.properties
city.name=Varanasi
city.dm=Mahesh 
Country.java
package com.concretepage;
public class Country {
  private String name;
  private String capital;
  //Setters and Getters
} 
City.java
package com.concretepage;
public class City {
  private String name;
  private String dm;
  private String countryName;
  //Setters and Getters
} 
SpringDemo.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemo {
  public static void main(String[] args) {
	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	ctx.register(AppConfig.class);
	ctx.refresh();
	Country c = ctx.getBean(Country.class);
	System.out.println(c.getName());
	System.out.println(c.getCapital());

	City city = ctx.getBean(City.class);
	System.out.println(city.getName());
	System.out.println(city.getDm());
	System.out.println(city.getCountryName());
  }
} 
Output
India
New Delhi
Varanasi
Mahesh
India 

Fetch Value from Property File

Once the property files are loaded by using @PropertySource, the values against keys can be accessed by using @Value and Environment in @Configuration class.
1. Using Environment.
Autowire Environment class.
@Autowired
Environment env; 
Now access the values against keys as following.
Country country = new Country();
country.setName(env.getProperty("country.name"));
country.setCapital(env.getProperty("country.capital")); 
2. Using @Value annotation.
Find the code to use @Value annotation to access values.
AppConfig.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;

@PropertySources({ 
  @PropertySource("classpath:/com/cp/myConfig1.properties"),
  @PropertySource("classpath:/com/cp/myConfig2.properties") 
})
@Configuration
public class AppConfig {
  @Value("${country.name}")
  String countryName;
  
  @Value("${country.capital}")
  String countryCapital;
  
  @Value("${city.name}")
  String cityName;
  
  @Value("${city.dm}")
  String cityDm;

  @Bean
  public Country getCountry() {
	Country country = new Country();
	country.setName(countryName);
	country.setCapital(countryCapital);
	return country;
  }

  @Bean
  public City getCity() {
	City city = new City();
	city.setName(cityName);
	city.setDm(cityDm);
	city.setCountryName(countryName);
	return city;
  }
} 

Property Overriding

If a property key exists in multiple property files, then the last @PropertySource annotation processed will override any previous key with the same name.
myConfig1.properties
country.name=India
country.capital=New Delhi 
myConfig2.properties
country.name=USA
city.name=Varanasi
city.dm=Mahesh 
We can see that the country.name exists in both the above property files.
@PropertySources({ 
  @PropertySource("classpath:/com/cp/myConfig1.properties"),
  @PropertySource("classpath:/com/cp/myConfig2.properties") 
})
@Configuration
public class AppConfig {
  @Value("${country.name}")
  String countryName;
  ------
} 
The value of countryName will be USA.

Resolving ${...} Placeholders

There can be ${...} placeholders in property file path passed in @PropertySource annotation and these ${...} placeholders can be resolved against the set of property sources already registered against the environment.
@PropertySource("classpath:/com/${prop.placeholder}/myConfig.properties") 
If placeholder is not found anywhere, for example in system variables or environment variables, we can define a default path with placeholder to avoid the error.
@PropertySource("classpath:/com/${prop.placeholder:default/path}/myConfig.properties") 
Now find the example. Here we will create a Spring test application. Using @TestPropertySource annotation, we will register the placeholder key and its value.
SpringAppTest.java
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = AppConfig.class)
@TestPropertySource(properties = { "prop.placeholder=cp" })
public class SpringAppTest {
  @Autowired
  private Country country;

  @Test
  public void test() {
	assertEquals("India", country.getName());
  }
} 
AppConfig.java
@PropertySource("classpath:/com/${prop.placeholder}/myConfig.properties")
@Configuration
public class AppConfig {
  @Autowired
  Environment env;

  @Bean
  public Country getCountry() {
	Country country = new Country();
	country.setName(env.getProperty("country.name"));
	country.setCapital(env.getProperty("country.capital"));
	return country;
  }
} 

Reference

Annotation Type PropertySource

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us