diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLoaders.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLoaders.java index 8ec01f80a0..c9636ed4cc 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLoaders.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLoaders.java @@ -51,21 +51,23 @@ class ConfigDataLoaders { * Create a new {@link ConfigDataLoaders} instance. * @param logFactory the deferred log factory * @param bootstrapContext the bootstrap context - * @param classLoader the class loader used when loading from {@code spring.factories} + * @param classLoader the class loader used when loading */ ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext, ClassLoader classLoader) { - this(logFactory, bootstrapContext, SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, classLoader)); + this(logFactory, bootstrapContext, classLoader, + SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, classLoader)); } /** * Create a new {@link ConfigDataLoaders} instance. * @param logFactory the deferred log factory * @param bootstrapContext the bootstrap context + * @param classLoader the class loader used when loading * @param names the {@link ConfigDataLoader} class names instantiate */ ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext, - List names) { + ClassLoader classLoader, List names) { this.logger = logFactory.getLog(getClass()); Instantiator> instantiator = new Instantiator<>(ConfigDataLoader.class, (availableParameters) -> { @@ -75,7 +77,7 @@ class ConfigDataLoaders { availableParameters.add(BootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapRegistry.class, bootstrapContext); }); - this.loaders = instantiator.instantiate(names); + this.loaders = instantiator.instantiate(classLoader, names); this.resourceTypes = getResourceTypes(this.loaders); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLocationResolvers.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLocationResolvers.java index 8280f9c25b..bfdc0ac5fe 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLocationResolvers.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataLocationResolvers.java @@ -77,7 +77,7 @@ class ConfigDataLocationResolvers { availableParameters.add(BootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapRegistry.class, bootstrapContext); }); - this.resolvers = reorder(instantiator.instantiate(names)); + this.resolvers = reorder(instantiator.instantiate(resourceLoader.getClassLoader(), names)); } private List> reorder(List> resolvers) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java index 68294e1632..366584760c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java @@ -17,6 +17,7 @@ package org.springframework.boot.env; import java.util.List; +import java.util.function.Function; import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.SpringApplication; @@ -28,6 +29,7 @@ import org.springframework.context.ApplicationEvent; import org.springframework.context.event.SmartApplicationListener; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.io.ResourceLoader; /** * {@link SmartApplicationListener} used to trigger {@link EnvironmentPostProcessor @@ -47,15 +49,14 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica private int order = DEFAULT_ORDER; - private final EnvironmentPostProcessorsFactory postProcessorsFactory; + private final Function postProcessorsFactory; /** * Create a new {@link EnvironmentPostProcessorApplicationListener} with * {@link EnvironmentPostProcessor} classes loaded via {@code spring.factories}. */ public EnvironmentPostProcessorApplicationListener() { - this(EnvironmentPostProcessorsFactory - .fromSpringFactories(EnvironmentPostProcessorApplicationListener.class.getClassLoader())); + this((classLoader) -> EnvironmentPostProcessorsFactory.fromSpringFactories(classLoader), new DeferredLogs()); } /** @@ -64,11 +65,11 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica * @param postProcessorsFactory the post processors factory */ public EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory) { - this(postProcessorsFactory, new DeferredLogs()); + this((classloader) -> postProcessorsFactory, new DeferredLogs()); } - EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory, - DeferredLogs deferredLogs) { + EnvironmentPostProcessorApplicationListener( + Function postProcessorsFactory, DeferredLogs deferredLogs) { this.postProcessorsFactory = postProcessorsFactory; this.deferredLogs = deferredLogs; } @@ -96,7 +97,8 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) { ConfigurableEnvironment environment = event.getEnvironment(); SpringApplication application = event.getSpringApplication(); - for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) { + for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(), + event.getBootstrapContext())) { postProcessor.postProcessEnvironment(environment, application); } } @@ -113,8 +115,11 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica this.deferredLogs.switchOverAll(); } - List getEnvironmentPostProcessors(ConfigurableBootstrapContext bootstrapContext) { - return this.postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext); + List getEnvironmentPostProcessors(ResourceLoader resourceLoader, + ConfigurableBootstrapContext bootstrapContext) { + ClassLoader classLoader = (resourceLoader != null) ? resourceLoader.getClassLoader() : null; + EnvironmentPostProcessorsFactory postProcessorsFactory = this.postProcessorsFactory.apply(classLoader); + return postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext); } @Override diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataLoadersTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataLoadersTests.java index b6ddb6e6ae..3bd6ad6a98 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataLoadersTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataLoadersTests.java @@ -53,13 +53,13 @@ class ConfigDataLoadersTests { @Test void createWhenLoaderHasLogParameterInjectsLog() { - new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(LoggingConfigDataLoader.class.getName())); } @Test void createWhenLoaderHasDeferredLogFactoryParameterInjectsDeferredLogFactory() { - ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(DeferredLogFactoryConfigDataLoader.class.getName())); assertThat(loaders).extracting("loaders").asList() .satisfies(this::containsValidDeferredLogFactoryConfigDataLoader); @@ -73,7 +73,7 @@ class ConfigDataLoadersTests { @Test void createWhenLoaderHasBootstrapParametersInjectsBootstrapContext() { - new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(BootstrappingConfigDataLoader.class.getName())); assertThat(this.bootstrapContext.get(String.class)).isEqualTo("boot"); } @@ -81,7 +81,7 @@ class ConfigDataLoadersTests { @Test void loadWhenSingleLoaderSupportsLocationReturnsLoadedConfigData() throws Exception { TestConfigDataResource location = new TestConfigDataResource("test"); - ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(TestConfigDataLoader.class.getName())); ConfigData loaded = loaders.load(this.context, location); assertThat(getLoader(loaded)).isInstanceOf(TestConfigDataLoader.class); @@ -90,7 +90,7 @@ class ConfigDataLoadersTests { @Test void loadWhenMultipleLoadersSupportLocationThrowsException() { TestConfigDataResource location = new TestConfigDataResource("test"); - ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(LoggingConfigDataLoader.class.getName(), TestConfigDataLoader.class.getName())); assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location)) .withMessageContaining("Multiple loaders found for resource 'test'"); @@ -99,7 +99,7 @@ class ConfigDataLoadersTests { @Test void loadWhenNoLoaderSupportsLocationThrowsException() { TestConfigDataResource location = new TestConfigDataResource("test"); - ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(NonLoadableConfigDataLoader.class.getName())); assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location)) .withMessage("No loader found for resource 'test'"); @@ -108,7 +108,7 @@ class ConfigDataLoadersTests { @Test void loadWhenGenericTypeDoesNotMatchSkipsLoader() throws Exception { TestConfigDataResource location = new TestConfigDataResource("test"); - ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, + ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null, Arrays.asList(OtherConfigDataLoader.class.getName(), SpecificConfigDataLoader.class.getName())); ConfigData loaded = loaders.load(this.context, location); assertThat(getLoader(loaded)).isInstanceOf(SpecificConfigDataLoader.class); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListenerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListenerTests.java index 82147c5587..2d2db32616 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListenerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/EnvironmentPostProcessorApplicationListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -50,19 +50,21 @@ class EnvironmentPostProcessorApplicationListenerTests { private DefaultBootstrapContext bootstrapContext = spy(new DefaultBootstrapContext()); private EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener( - EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class), this.deferredLogs); + (classLoader) -> EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class), + this.deferredLogs); @Test void createUsesSpringFactories() { EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener(); - assertThat(listener.getEnvironmentPostProcessors(this.bootstrapContext)).hasSizeGreaterThan(1); + assertThat(listener.getEnvironmentPostProcessors(null, this.bootstrapContext)).hasSizeGreaterThan(1); } @Test void createWhenHasFactoryUsesFactory() { EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener( EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class)); - List postProcessors = listener.getEnvironmentPostProcessors(this.bootstrapContext); + List postProcessors = listener.getEnvironmentPostProcessors(null, + this.bootstrapContext); assertThat(postProcessors).hasSize(1); assertThat(postProcessors.get(0)).isInstanceOf(TestEnvironmentPostProcessor.class); }