Merge branch 'master' into 2.0.x
This commit is contained in:
@@ -19,10 +19,13 @@ package org.springframework.cloud.bootstrap;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.boot.Banner.Mode;
|
||||
@@ -31,6 +34,7 @@ import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.boot.context.logging.LoggingApplicationListener;
|
||||
import org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -44,9 +48,9 @@ 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.PropertySource.StubPropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.env.SystemEnvironmentPropertySource;
|
||||
import org.springframework.core.env.PropertySource.StubPropertySource;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -165,6 +169,14 @@ public class BootstrapApplicationListener
|
||||
// Don't use the default properties in this builder
|
||||
.registerShutdownHook(false).logStartupInfo(false)
|
||||
.web(WebApplicationType.NONE);
|
||||
if (environment.getPropertySources().contains("refreshArgs")) {
|
||||
// If we are doing a context refresh, really we only want to refresh the
|
||||
// Environment, and there are some toxic listeners (like the
|
||||
// LoggingApplicationListener) that affect global static state, so we need a
|
||||
// way to switch those off.
|
||||
builder.application()
|
||||
.setListeners(filterListeners(builder.application().getListeners()));
|
||||
}
|
||||
List<Class<?>> sources = new ArrayList<>();
|
||||
for (String name : names) {
|
||||
Class<?> cls = ClassUtils.resolveClassName(name, null);
|
||||
@@ -180,7 +192,8 @@ public class BootstrapApplicationListener
|
||||
builder.sources(sources.toArray(new Class[sources.size()]));
|
||||
final ConfigurableApplicationContext context = builder.run();
|
||||
// gh-214 using spring.application.name=bootstrap to set the context id via
|
||||
// `ContextIdApplicationContextInitializer` prevents apps from getting the actual spring.application.name
|
||||
// `ContextIdApplicationContextInitializer` prevents apps from getting the actual
|
||||
// spring.application.name
|
||||
// during the bootstrap phase.
|
||||
context.setId("bootstrap");
|
||||
// Make the bootstrap context a parent of the app context
|
||||
@@ -192,6 +205,18 @@ public class BootstrapApplicationListener
|
||||
return context;
|
||||
}
|
||||
|
||||
private Collection<? extends ApplicationListener<?>> filterListeners(
|
||||
Set<ApplicationListener<?>> listeners) {
|
||||
Set<ApplicationListener<?>> result = new LinkedHashSet<>();
|
||||
for (ApplicationListener<?> listener : listeners) {
|
||||
if (!(listener instanceof LoggingApplicationListener)
|
||||
&& !(listener instanceof LoggingSystemShutdownListener)) {
|
||||
result.add(listener);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void mergeDefaultProperties(MutablePropertySources environment,
|
||||
MutablePropertySources bootstrap) {
|
||||
String name = DEFAULT_PROPERTIES;
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package org.springframework.cloud.context.refresh;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.test.util.TestPropertyValues.Type;
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
@@ -22,10 +23,18 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ContextRefresherTests {
|
||||
|
||||
private RefreshScope scope = Mockito.mock(RefreshScope.class);
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
System.clearProperty(LoggingSystem.SYSTEM_PROPERTY);
|
||||
TestLoggingSystem.count = 0;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orderNewPropertiesConsistentWithNewContext() {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class,
|
||||
@@ -38,8 +47,8 @@ public class ContextRefresherTests {
|
||||
ContextRefresher refresher = new ContextRefresher(context, scope);
|
||||
refresher.refresh();
|
||||
names = names(context.getEnvironment().getPropertySources());
|
||||
assertThat(names)
|
||||
.contains("applicationConfig: [classpath:/bootstrap-refresh.properties]");
|
||||
assertThat(names).contains(
|
||||
"applicationConfig: [classpath:/bootstrap-refresh.properties]");
|
||||
assertThat(names).containsSequence(
|
||||
"applicationConfig: [classpath:/application.properties]",
|
||||
"applicationConfig: [classpath:/bootstrap-refresh.properties]",
|
||||
@@ -53,7 +62,8 @@ public class ContextRefresherTests {
|
||||
// a bootstrapProperties immediately
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class,
|
||||
"--spring.main.webEnvironment=false", "--debug=false",
|
||||
"--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh")) {
|
||||
"--spring.main.bannerMode=OFF",
|
||||
"--spring.cloud.bootstrap.name=refresh")) {
|
||||
List<String> names = names(context.getEnvironment().getPropertySources());
|
||||
System.err.println("***** " + context.getEnvironment().getPropertySources());
|
||||
assertThat(names).doesNotContain("bootstrapProperties");
|
||||
@@ -71,19 +81,42 @@ public class ContextRefresherTests {
|
||||
public void parentContextIsClosed() {
|
||||
// Use spring.cloud.bootstrap.name to switch off the defaults (which would pick up
|
||||
// a bootstrapProperties immediately
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(ContextRefresherTests.class,
|
||||
"--spring.main.webEnvironment=false", "--debug=false",
|
||||
"--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh")) {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
ContextRefresherTests.class, "--spring.main.webEnvironment=false",
|
||||
"--debug=false", "--spring.main.bannerMode=OFF",
|
||||
"--spring.cloud.bootstrap.name=refresh")) {
|
||||
ContextRefresher refresher = new ContextRefresher(context, scope);
|
||||
TestPropertyValues.of(
|
||||
"spring.cloud.bootstrap.sources: org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration")
|
||||
.applyTo(context);
|
||||
ConfigurableApplicationContext refresherContext = refresher.addConfigFilesToEnvironment();
|
||||
assertThat(refresherContext.getParent()).isNotNull().isInstanceOf(ConfigurableApplicationContext.class);
|
||||
ConfigurableApplicationContext parent = (ConfigurableApplicationContext) refresherContext.getParent();
|
||||
ConfigurableApplicationContext refresherContext = refresher
|
||||
.addConfigFilesToEnvironment();
|
||||
assertThat(refresherContext.getParent()).isNotNull()
|
||||
.isInstanceOf(ConfigurableApplicationContext.class);
|
||||
ConfigurableApplicationContext parent = (ConfigurableApplicationContext) refresherContext
|
||||
.getParent();
|
||||
assertThat(parent.isActive()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loggingSystemNotInitialized() {
|
||||
System.setProperty(LoggingSystem.SYSTEM_PROPERTY,
|
||||
TestLoggingSystem.class.getName());
|
||||
TestLoggingSystem system = (TestLoggingSystem) LoggingSystem
|
||||
.get(getClass().getClassLoader());
|
||||
assertThat(system.getCount()).isEqualTo(0);
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class,
|
||||
"--spring.main.webEnvironment=false", "--debug=false",
|
||||
"--spring.main.bannerMode=OFF",
|
||||
"--spring.cloud.bootstrap.name=refresh")) {
|
||||
assertThat(system.getCount()).isEqualTo(4);
|
||||
ContextRefresher refresher = new ContextRefresher(context, scope);
|
||||
refresher.refresh();
|
||||
assertThat(system.getCount()).isEqualTo(4);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> names(MutablePropertySources propertySources) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (PropertySource<?> p : propertySources) {
|
||||
@@ -95,7 +128,7 @@ public class ContextRefresherTests {
|
||||
@Configuration
|
||||
protected static class Empty {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
// This is added to bootstrap context as a source in bootstrap.properties
|
||||
protected static class PropertySourceConfiguration implements PropertySourceLocator {
|
||||
@@ -110,4 +143,22 @@ public class ContextRefresherTests {
|
||||
|
||||
}
|
||||
|
||||
public static class TestLoggingSystem extends LoggingSystem {
|
||||
|
||||
private static int count;
|
||||
|
||||
public TestLoggingSystem(ClassLoader loader) {
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeInitialize() {
|
||||
count++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user