Adjust @PropertySource handling so @Conditionals are accounted for
User can now do this, for instance: @Configuration @PropertySource("classpath:my.properties") public class MainConfiguration {} @Configuration @PropertySource("classpath:foo.properties") @Profile("foo") public class FooConfiguration {} and the "foo" properties ar eonly loaded in the "foo" profile.
This commit is contained in:
parent
6c4ee0b05d
commit
22762f2004
|
@ -28,6 +28,7 @@ import java.util.Random;
|
|||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.SpringApplicationInitializer;
|
||||
import org.springframework.boot.bind.PropertySourcesPropertyValues;
|
||||
|
@ -38,6 +39,7 @@ import org.springframework.boot.config.YamlPropertySourceLoader;
|
|||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||
import org.springframework.context.annotation.PropertySources;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
|
@ -150,7 +152,7 @@ public class ConfigFileApplicationContextInitializer implements
|
|||
for (AnnotationAttributes propertySource : attributesForRepeatable(
|
||||
new StandardAnnotationMetadata(type), PropertySources.class,
|
||||
org.springframework.context.annotation.PropertySource.class)) {
|
||||
this.propertySourceAnnotations.add(
|
||||
this.propertySourceAnnotations.add(type,
|
||||
propertySource.getStringArray("value"),
|
||||
propertySource.getBoolean("ignoreResourceNotFound"),
|
||||
propertySource.getString("name"));
|
||||
|
@ -255,11 +257,16 @@ public class ConfigFileApplicationContextInitializer implements
|
|||
ResourceLoader resourceLoader, String location, String profile) {
|
||||
location = environment.resolvePlaceholders(location);
|
||||
String suffix = "." + StringUtils.getFilenameExtension(location);
|
||||
Class<?> type = this.propertySourceAnnotations.configuration(location);
|
||||
|
||||
if (StringUtils.hasLength(profile)) {
|
||||
location = location.replace(suffix, "-" + profile + suffix);
|
||||
}
|
||||
|
||||
if (isPropertySourceAnnotationOnExcludedType(profile, type, location)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<PropertySourceLoader> loaders = new ArrayList<PropertySourceLoader>();
|
||||
loaders.add(new PropertiesPropertySourceLoader());
|
||||
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
|
||||
|
@ -289,6 +296,30 @@ public class ConfigFileApplicationContextInitializer implements
|
|||
return propertySource;
|
||||
}
|
||||
|
||||
private boolean isPropertySourceAnnotationOnExcludedType(String profile,
|
||||
Class<?> type, String location) {
|
||||
if (type == null) {
|
||||
// No configuration class to worry about, just a vanilla properties location
|
||||
return false;
|
||||
}
|
||||
if (StringUtils.hasText(profile)
|
||||
&& !this.propertySourceAnnotations.locations().contains(location)) {
|
||||
// We are looking for profile specific properties and this one isn't
|
||||
// explicitly asked for in propertySourceAnnotations
|
||||
return true;
|
||||
}
|
||||
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(
|
||||
new DefaultListableBeanFactory(), this.environment);
|
||||
int before = reader.getRegistry().getBeanDefinitionCount();
|
||||
reader.register(type);
|
||||
int after = reader.getRegistry().getBeanDefinitionCount();
|
||||
if (after == before) {
|
||||
// The configuration class was @Conditional and excluded
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PropertySource<?> getPropertySource(String name, Resource resource,
|
||||
String profile, List<PropertySourceLoader> loaders) {
|
||||
String key = resource.getDescription() + (profile == null ? "" : "#" + profile);
|
||||
|
@ -364,23 +395,31 @@ public class ConfigFileApplicationContextInitializer implements
|
|||
|
||||
private Map<String, String> names = new HashMap<String, String>();
|
||||
|
||||
private Map<String, Class<?>> configs = new HashMap<String, Class<?>>();
|
||||
|
||||
private Map<String, Boolean> ignores = new HashMap<String, Boolean>();
|
||||
|
||||
public void add(String[] locations, boolean ignoreResourceNotFound, String name) {
|
||||
public void add(Class<?> source, String[] locations,
|
||||
boolean ignoreResourceNotFound, String name) {
|
||||
this.locations.addAll(Arrays.asList(locations));
|
||||
if (StringUtils.hasText(name)) {
|
||||
for (String location : locations) {
|
||||
this.names.put(location, name);
|
||||
}
|
||||
for (String location : locations) {
|
||||
boolean reallyIgnore = ignoreResourceNotFound;
|
||||
if (this.ignores.containsKey(location)) {
|
||||
// Only if they all ignore this location will it be ignored
|
||||
reallyIgnore &= this.ignores.get(location);
|
||||
}
|
||||
this.ignores.put(location, reallyIgnore);
|
||||
}
|
||||
}
|
||||
for (String location : locations) {
|
||||
boolean reallyIgnore = ignoreResourceNotFound;
|
||||
if (this.ignores.containsKey(location)) {
|
||||
// Only if they all ignore this location will it be ignored
|
||||
reallyIgnore &= this.ignores.get(location);
|
||||
}
|
||||
this.ignores.put(location, reallyIgnore);
|
||||
this.configs.put(location, source);
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> configuration(String location) {
|
||||
return this.configs.get(location);
|
||||
}
|
||||
|
||||
public boolean ignoreResourceNotFound(String location) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.junit.Test;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
@ -34,6 +35,7 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
|
@ -196,6 +198,35 @@ public class ConfigFileApplicationContextInitializerTests {
|
|||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourceAnnotationInProfile() throws Exception {
|
||||
SpringApplication application = new SpringApplication(
|
||||
WithPropertySourceInProfile.class);
|
||||
application.setWebEnvironment(false);
|
||||
ConfigurableApplicationContext context = application
|
||||
.run("--spring.profiles.active=myprofile");
|
||||
String property = context.getEnvironment().getProperty("my.property");
|
||||
assertThat(property, equalTo("frompropertiesfile"));
|
||||
assertNotNull(context.getEnvironment().getPropertySources()
|
||||
.get("classpath:/enableprofile.properties"));
|
||||
assertNull(context.getEnvironment().getPropertySources()
|
||||
.get("classpath:/enableprofile-myprofile.properties"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourceAnnotationAndProfile() throws Exception {
|
||||
SpringApplication application = new SpringApplication(
|
||||
WithPropertySourceAndProfile.class);
|
||||
application.setWebEnvironment(false);
|
||||
ConfigurableApplicationContext context = application.run();
|
||||
String property = context.getEnvironment().getProperty("my.property");
|
||||
assertThat(property, equalTo(null));
|
||||
assertNull(context.getEnvironment().getPropertySources()
|
||||
.get("classpath:/enableprofile-myprofile.properties"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourceAnnotationMultipleLocations() throws Exception {
|
||||
SpringApplication application = new SpringApplication(
|
||||
|
@ -242,6 +273,19 @@ public class ConfigFileApplicationContextInitializerTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:/enableprofile.properties")
|
||||
protected static class WithPropertySourceInProfile {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:/enableprofile-myprofile.properties")
|
||||
@Profile("myprofile")
|
||||
protected static class WithPropertySourceAndProfile {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@PropertySource({ "classpath:/specificlocation.properties",
|
||||
"classpath:/moreproperties.properties" })
|
||||
|
|
Loading…
Reference in New Issue