Merge branch '1.1.x'
This commit is contained in:
@@ -17,6 +17,12 @@
|
||||
|
||||
package org.springframework.cloud.autoconfigure;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -29,6 +35,7 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Autoconfiguration for the refresh scope and associated features to do with changes in
|
||||
@@ -42,10 +49,24 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
|
||||
public class RefreshAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public static RefreshScope refreshScope() {
|
||||
return new RefreshScope();
|
||||
@Component
|
||||
@ConditionalOnMissingBean(RefreshScope.class)
|
||||
protected static class RefreshScopeConfiguration
|
||||
implements BeanDefinitionRegistryPostProcessor {
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
|
||||
throws BeansException {
|
||||
registry.registerBeanDefinition("refreshScope",
|
||||
BeanDefinitionBuilder.genericBeanDefinition(RefreshScope.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.bootstrap;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -46,6 +47,7 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.env.SystemEnvironmentPropertySource;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -81,26 +83,56 @@ public class BootstrapApplicationListener
|
||||
if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
|
||||
return;
|
||||
}
|
||||
for (ApplicationContextInitializer<?> initializer : event.getSpringApplication().getInitializers()) {
|
||||
ConfigurableApplicationContext context = null;
|
||||
String configName = environment
|
||||
.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
|
||||
for (ApplicationContextInitializer<?> initializer : event.getSpringApplication()
|
||||
.getInitializers()) {
|
||||
if (initializer instanceof ParentContextApplicationContextInitializer) {
|
||||
return;
|
||||
context = findBootstrapContext(
|
||||
(ParentContextApplicationContextInitializer) initializer,
|
||||
configName);
|
||||
}
|
||||
}
|
||||
ConfigurableApplicationContext context = bootstrapServiceContext(environment,
|
||||
event.getSpringApplication());
|
||||
if (context == null) {
|
||||
context = bootstrapServiceContext(environment, event.getSpringApplication(),
|
||||
configName);
|
||||
}
|
||||
apply(context, event.getSpringApplication(), environment);
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext findBootstrapContext(
|
||||
ParentContextApplicationContextInitializer initializer, String configName) {
|
||||
Field field = ReflectionUtils
|
||||
.findField(ParentContextApplicationContextInitializer.class, "parent");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
ConfigurableApplicationContext parent = safeCast(
|
||||
ConfigurableApplicationContext.class,
|
||||
ReflectionUtils.getField(field, initializer));
|
||||
if (parent != null && !configName.equals(parent.getId())) {
|
||||
parent = safeCast(ConfigurableApplicationContext.class, parent.getParent());
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
private <T> T safeCast(Class<T> type, Object object) {
|
||||
try {
|
||||
return type.cast(object);
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext bootstrapServiceContext(
|
||||
ConfigurableEnvironment environment, final SpringApplication application) {
|
||||
ConfigurableEnvironment environment, final SpringApplication application,
|
||||
String configName) {
|
||||
StandardEnvironment bootstrapEnvironment = new StandardEnvironment();
|
||||
MutablePropertySources bootstrapProperties = bootstrapEnvironment
|
||||
.getPropertySources();
|
||||
for (PropertySource<?> source : bootstrapProperties) {
|
||||
bootstrapProperties.remove(source.getName());
|
||||
}
|
||||
String configName = environment
|
||||
.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
|
||||
String configLocation = environment
|
||||
.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
|
||||
Map<String, Object> bootstrapMap = new HashMap<>();
|
||||
|
||||
@@ -6,6 +6,7 @@ import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.springframework.cloud.autoconfigure;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.OutputCapture;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RefreshAutoConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public OutputCapture output = new OutputCapture();
|
||||
|
||||
@Test
|
||||
public void noWarnings() {
|
||||
try (ConfigurableApplicationContext context = getApplicationContext(
|
||||
Config.class)) {
|
||||
assertTrue(context.containsBean("refreshScope"));
|
||||
assertThat(output.toString(), not(containsString("WARN")));
|
||||
}
|
||||
}
|
||||
|
||||
private static ConfigurableApplicationContext getApplicationContext(
|
||||
Class<?> configuration, String... properties) {
|
||||
return new SpringApplicationBuilder(configuration).web(false)
|
||||
.properties(properties).run();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class Config {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
package org.springframework.cloud.bootstrap;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import static org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapConfiguration.firstToBeCreated;
|
||||
|
||||
@@ -8,10 +16,28 @@ import static org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapCon
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Order(0)
|
||||
@Configuration
|
||||
public class TestBootstrapConfiguration {
|
||||
|
||||
public TestBootstrapConfiguration() {
|
||||
firstToBeCreated.compareAndSet(null, TestBootstrapConfiguration.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApplicationContextInitializer<ConfigurableApplicationContext> customInitializer() {
|
||||
return new ApplicationContextInitializer<ConfigurableApplicationContext>() {
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
ConfigurableEnvironment environment = applicationContext.getEnvironment();
|
||||
environment.getPropertySources()
|
||||
.addLast(new MapPropertySource("customProperties",
|
||||
Collections.<String, Object>singletonMap("custom.foo",
|
||||
environment.resolvePlaceholders(
|
||||
"${spring.application.name:bar}"))));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -54,6 +55,8 @@ public class BootstrapConfigurationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
private ConfigurableApplicationContext sibling;
|
||||
|
||||
@Rule
|
||||
public ExpectedException expected = ExpectedException.none();
|
||||
|
||||
@@ -68,6 +71,9 @@ public class BootstrapConfigurationTests {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
if (this.sibling != null) {
|
||||
this.sibling.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -197,7 +203,7 @@ public class BootstrapConfigurationTests {
|
||||
PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "true");
|
||||
ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
environment.getPropertySources().addLast(new MapPropertySource("last",
|
||||
Collections.<String, Object> singletonMap("bootstrap.foo", "splat")));
|
||||
Collections.<String, Object>singletonMap("bootstrap.foo", "splat")));
|
||||
this.context = new SpringApplicationBuilder().web(false).environment(environment)
|
||||
.sources(BareConfiguration.class).run();
|
||||
assertEquals("splat", this.context.getEnvironment().getProperty("bootstrap.foo"));
|
||||
@@ -282,6 +288,32 @@ public class BootstrapConfigurationTests {
|
||||
assertNotNull(context.getParent());
|
||||
assertEquals("bootstrap", context.getParent().getParent().getId());
|
||||
assertNull(context.getParent().getParent().getParent());
|
||||
assertEquals("bar", context.getEnvironment().getProperty("custom.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bootstrapContextSharedBySiblings() {
|
||||
TestHigherPriorityBootstrapConfiguration.count.set(0);
|
||||
PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar");
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder()
|
||||
.sources(BareConfiguration.class);
|
||||
this.sibling = builder.child(BareConfiguration.class)
|
||||
.properties("spring.application.name=sibling").web(false).run();
|
||||
this.context = builder.child(BareConfiguration.class)
|
||||
.properties("spring.application.name=context").web(false).run();
|
||||
assertEquals(1, TestHigherPriorityBootstrapConfiguration.count.get());
|
||||
assertNotNull(context.getParent());
|
||||
assertEquals("bootstrap", context.getParent().getParent().getId());
|
||||
assertNull(context.getParent().getParent().getParent());
|
||||
assertEquals("context", context.getEnvironment().getProperty("custom.foo"));
|
||||
assertEquals("context",
|
||||
context.getEnvironment().getProperty("spring.application.name"));
|
||||
assertNotNull(sibling.getParent());
|
||||
assertEquals("bootstrap", sibling.getParent().getParent().getId());
|
||||
assertNull(sibling.getParent().getParent().getParent());
|
||||
assertEquals("sibling", sibling.getEnvironment().getProperty("custom.foo"));
|
||||
assertEquals("sibling",
|
||||
sibling.getEnvironment().getProperty("spring.application.name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -349,7 +381,7 @@ public class BootstrapConfigurationTests {
|
||||
protected static class PropertySourceConfiguration implements PropertySourceLocator {
|
||||
|
||||
public static Map<String, Object> MAP = new HashMap<String, Object>(
|
||||
Collections.<String, Object> singletonMap("bootstrap.foo", "bar"));
|
||||
Collections.<String, Object>singletonMap("bootstrap.foo", "bar"));
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
@@ -21,11 +21,13 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -36,7 +38,6 @@ import org.springframework.cloud.context.scope.refresh.RefreshScopeLazyIntegrati
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
@@ -198,7 +199,7 @@ public class RefreshScopeLazyIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TestProperties.class)
|
||||
@Import({ RefreshAutoConfiguration.class,
|
||||
@ImportAutoConfiguration({ RefreshAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected static class TestConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user