diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java index ef243173..1f23cbfa 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java @@ -111,6 +111,10 @@ public class BootstrapApplicationListener // Use names and ensure unique to protect against duplicates List names = SpringFactoriesLoader .loadFactoryNames(BootstrapConfiguration.class, classLoader); + for (String name : StringUtils.commaDelimitedListToStringArray( + environment.getProperty("spring.cloud.bootstrap.sources", ""))) { + names.add(name); + } // TODO: is it possible or sensible to share a ResourceLoader? SpringApplicationBuilder builder = new SpringApplicationBuilder() .profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF) diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java index 41096da6..2b5998e3 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java @@ -37,6 +37,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; @@ -52,6 +53,8 @@ import org.springframework.web.context.support.StandardServletEnvironment; @ManagedResource public class RefreshEndpoint extends AbstractEndpoint> { + private static final String REFRESH_ARGS_PROPERTY_SOURCE = "refreshArgs"; + private Set standardSources = new HashSet( Arrays.asList(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, @@ -88,6 +91,9 @@ public class RefreshEndpoint extends AbstractEndpoint> { this.context.getEnvironment()); capture = new SpringApplicationBuilder(Empty.class).bannerMode(Mode.OFF) .web(false).environment(environment).run(); + if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) { + environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE); + } MutablePropertySources target = this.context.getEnvironment() .getPropertySources(); String targetName = null; @@ -144,6 +150,11 @@ public class RefreshEndpoint extends AbstractEndpoint> { } environment.setActiveProfiles(input.getActiveProfiles()); environment.setDefaultProfiles(input.getDefaultProfiles()); + Map map = new HashMap(); + map.put("spring.jmx.enabled", false); + map.put("spring.main.sources", ""); + capturedPropertySources + .addFirst(new MapPropertySource(REFRESH_ARGS_PROPERTY_SOURCE, map)); return environment; } diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java index a9a82d25..10658e02 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java @@ -44,6 +44,7 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -96,12 +97,30 @@ public class RefreshEndpointTests { RefreshScope scope = new RefreshScope(); scope.setApplicationContext(this.context); EnvironmentTestUtils.addEnvironment(this.context, - "spring.main.sources=" + ExternalPropertySourceLocator.class.getName()); + "spring.cloud.bootstrap.sources=" + + ExternalPropertySourceLocator.class.getName()); RefreshEndpoint endpoint = new RefreshEndpoint(this.context, scope); Collection keys = endpoint.invoke(); assertTrue("Wrong keys: " + keys, keys.contains("external.message")); } + @Test + public void springMainSourcesEmptyInRefreshCycle() throws Exception { + this.context = new SpringApplicationBuilder(Empty.class).web(false) + .bannerMode(Mode.OFF).properties("spring.cloud.bootstrap.name:none") + .run(); + RefreshScope scope = new RefreshScope(); + scope.setApplicationContext(this.context); + // spring.main.sources should be empty when the refresh cycle starts (we don't + // want any config files from the application context getting into the one used to + // construct the environment for refresh) + EnvironmentTestUtils.addEnvironment(this.context, + "spring.main.sources=" + ExternalPropertySourceLocator.class.getName()); + RefreshEndpoint endpoint = new RefreshEndpoint(this.context, scope); + Collection keys = endpoint.invoke(); + assertFalse("Wrong keys: " + keys, keys.contains("external.message")); + } + @Test public void eventsPublishedInOrder() throws Exception { this.context = new SpringApplicationBuilder(Empty.class).web(false)