diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java new file mode 100644 index 00000000..cb7a2207 --- /dev/null +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.bootstrap; + +import org.springframework.boot.BootstrapContext; +import org.springframework.boot.BootstrapRegistry; +import org.springframework.boot.BootstrapRegistryInitializer; +import org.springframework.cloud.context.refresh.ConfigDataContextRefresher; + +/** + * BootstrapRegistryInitializer that adds the BootstrapContext to the ApplicationContext + * for use later in {@link ConfigDataContextRefresher}. + * + * @author Spencer Gibb + * @since 3.0.3 + */ +public class RefreshBootstrapRegistryInitializer implements BootstrapRegistryInitializer { + + @Override + public void initialize(BootstrapRegistry registry) { + // promote BootstrapContext to context + registry.addCloseListener(event -> { + BootstrapContext bootstrapContext = event.getBootstrapContext(); + event.getApplicationContext().getBeanFactory().registerSingleton("bootstrapContext", bootstrapContext); + }); + } + +} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java index 19fac06c..d4ac7100 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java @@ -16,7 +16,7 @@ package org.springframework.cloud.context.refresh; -import org.springframework.boot.DefaultBootstrapContext; +import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.context.scope.refresh.RefreshScope; @@ -50,8 +50,9 @@ public class ConfigDataContextRefresher extends ContextRefresher { StandardEnvironment environment = copyEnvironment(getContext().getEnvironment()); String[] activeProfiles = getContext().getEnvironment().getActiveProfiles(); DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); - ConfigDataEnvironmentPostProcessor.applyTo(environment, resourceLoader, new DefaultBootstrapContext(), - activeProfiles); + ConfigurableBootstrapContext bootstrapContext = getContext().getBean("bootstrapContext", + ConfigurableBootstrapContext.class); + ConfigDataEnvironmentPostProcessor.applyTo(environment, resourceLoader, bootstrapContext, activeProfiles); if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) { environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE); diff --git a/spring-cloud-context/src/main/resources/META-INF/spring.factories b/spring-cloud-context/src/main/resources/META-INF/spring.factories index 85783673..745182fe 100644 --- a/spring-cloud-context/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-context/src/main/resources/META-INF/spring.factories @@ -16,6 +16,9 @@ org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration, org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\ org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration +# Spring Boot BootstrapRegistryInitializer +org.springframework.boot.BootstrapRegistryInitializer=\ +org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer # Spring Boot Bootstrappers org.springframework.boot.Bootstrapper=\ org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java index 6d902449..99d85b85 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java @@ -27,6 +27,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.BootstrapRegistry.InstanceSupplier; +import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.config.ConfigData; @@ -129,6 +131,13 @@ public class ConfigDataContextRefresherIntegrationTests { then(cachedRandomLong).isEqualTo(properties.cachedRandomLong); } + @Test + public void contextContainsBootstrapContext() { + ConfigurableBootstrapContext bootstrapContext = context.getBean(ConfigurableBootstrapContext.class); + then(bootstrapContext).isNotNull(); + then(bootstrapContext.isRegistered(MyTestBean.class)).isTrue(); + } + protected static class TestEnvPostProcessor implements EnvironmentPostProcessor, Ordered { @Override @@ -189,6 +198,7 @@ public class ConfigDataContextRefresherIntegrationTests { public List resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException { + context.getBootstrapContext().registerIfAbsent(MyTestBean.class, InstanceSupplier.of(new MyTestBean())); return Collections.singletonList(new TestConfigDataResource(count.get())); } @@ -206,6 +216,10 @@ public class ConfigDataContextRefresherIntegrationTests { } + protected static class MyTestBean { + + } + @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(TestProperties.class) @EnableAutoConfiguration