diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java index d3a0eba3547..e6de58c8aeb 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java @@ -25,6 +25,7 @@ import java.util.Set; import org.apache.commons.logging.Log; +import org.springframework.boot.BootstrapRegistry.InstanceSupplier; import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.DefaultPropertiesPropertySource; import org.springframework.boot.context.config.ConfigDataEnvironmentContributors.BinderOption; @@ -198,8 +199,12 @@ class ConfigDataEnvironment { */ void processAndApply() { ConfigDataImporter importer = new ConfigDataImporter(this.resolvers, this.loaders); + this.bootstrapContext.register(Binder.class, InstanceSupplier + .from(() -> this.contributors.getBinder(null, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE))); ConfigDataEnvironmentContributors contributors = processInitial(this.contributors, importer); - ConfigDataActivationContext activationContext = createActivationContext(contributors); + Binder initialBinder = contributors.getBinder(null, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE); + this.bootstrapContext.register(Binder.class, InstanceSupplier.of(initialBinder)); + ConfigDataActivationContext activationContext = createActivationContext(initialBinder); contributors = processWithoutProfiles(contributors, importer, activationContext); activationContext = withProfiles(contributors, activationContext); contributors = processWithProfiles(contributors, importer, activationContext); @@ -212,11 +217,10 @@ class ConfigDataEnvironment { return contributors.withProcessedImports(importer, null); } - private ConfigDataActivationContext createActivationContext(ConfigDataEnvironmentContributors contributors) { + private ConfigDataActivationContext createActivationContext(Binder initialBinder) { this.logger.trace("Creating config data activation context from initial contributions"); - Binder binder = contributors.getBinder(null, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE); try { - return new ConfigDataActivationContext(this.environment, binder); + return new ConfigDataActivationContext(this.environment, initialBinder); } catch (BindException ex) { if (ex.getCause() instanceof InactiveConfigDataAccessException) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests.java similarity index 93% rename from spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests.java rename to spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests.java index bf6a8a3d0ff..9ea73591825 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests.java @@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Phillip Webb */ -class ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests { +class ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests { private SpringApplication application; @@ -50,6 +50,7 @@ class ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests { .run("--spring.config.import=classpath:application-bootstrap-registry-integration-tests.properties")) { LoaderHelper bean = context.getBean(TestConfigDataBootstrap.LoaderHelper.class); assertThat(bean).isNotNull(); + assertThat(bean.getBound()).isEqualTo("igotbound"); assertThat(bean.getLocation().getResolverHelper().getLocation()).isEqualTo("testbootstrap:test"); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/TestConfigDataBootstrap.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/TestConfigDataBootstrap.java index 6e0abfcc731..adec00f15f1 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/TestConfigDataBootstrap.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/TestConfigDataBootstrap.java @@ -19,15 +19,17 @@ package org.springframework.boot.context.config; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import org.springframework.boot.BootstrapContextClosedEvent; import org.springframework.boot.BootstrapRegistry.InstanceSupplier; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.ApplicationListener; import org.springframework.core.env.MapPropertySource; /** * Test classes used with - * {@link ConfigDataEnvironmentPostProcessorBootstrapRegistryIntegrationTests} to show how + * {@link ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests} to show how * a bootstrap registry can be used. This example will create helper instances during * result and load. It also shows how the helper can ultimately be registered as a bean. * @@ -57,7 +59,7 @@ class TestConfigDataBootstrap { @Override public ConfigData load(ConfigDataLoaderContext context, Location location) throws IOException { context.getBootstrapContext().registerIfAbsent(LoaderHelper.class, - InstanceSupplier.from(() -> new LoaderHelper(location))); + (bootstrapContext) -> new LoaderHelper(location, () -> bootstrapContext.get(Binder.class))); LoaderHelper helper = context.getBootstrapContext().get(LoaderHelper.class); context.getBootstrapContext().addCloseListener(helper); return new ConfigData( @@ -103,14 +105,21 @@ class TestConfigDataBootstrap { private final Location location; - LoaderHelper(Location location) { + private final Supplier binder; + + LoaderHelper(Location location, Supplier binder) { this.location = location; + this.binder = binder; } Location getLocation() { return this.location; } + String getBound() { + return this.binder.get().bind("myprop", String.class).orElse(null); + } + @Override public void onApplicationEvent(BootstrapContextClosedEvent event) { event.getApplicationContext().getBeanFactory().registerSingleton("loaderHelper", this); diff --git a/spring-boot-project/spring-boot/src/test/resources/application-bootstrap-registry-integration-tests.properties b/spring-boot-project/spring-boot/src/test/resources/application-bootstrap-registry-integration-tests.properties index 5a1fdceb704..c354f473376 100644 --- a/spring-boot-project/spring-boot/src/test/resources/application-bootstrap-registry-integration-tests.properties +++ b/spring-boot-project/spring-boot/src/test/resources/application-bootstrap-registry-integration-tests.properties @@ -1 +1,2 @@ -spring.config.import=testbootstrap:test \ No newline at end of file +spring.config.import=testbootstrap:test +myprop=igotbound