Pass ResourceLoader.getClassLoader() to Instantiator

Update calls to `Instantiator` to that they also include
`ResourceLoader.getClassLoader()`.

Closes gh-27071
pull/27157/head
Phillip Webb 3 years ago
parent 641dfbdf98
commit b093db104c

@ -51,21 +51,23 @@ class ConfigDataLoaders {
* Create a new {@link ConfigDataLoaders} instance. * Create a new {@link ConfigDataLoaders} instance.
* @param logFactory the deferred log factory * @param logFactory the deferred log factory
* @param bootstrapContext the bootstrap context * @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, ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
ClassLoader classLoader) { 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. * Create a new {@link ConfigDataLoaders} instance.
* @param logFactory the deferred log factory * @param logFactory the deferred log factory
* @param bootstrapContext the bootstrap context * @param bootstrapContext the bootstrap context
* @param classLoader the class loader used when loading
* @param names the {@link ConfigDataLoader} class names instantiate * @param names the {@link ConfigDataLoader} class names instantiate
*/ */
ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext, ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
List<String> names) { ClassLoader classLoader, List<String> names) {
this.logger = logFactory.getLog(getClass()); this.logger = logFactory.getLog(getClass());
Instantiator<ConfigDataLoader<?>> instantiator = new Instantiator<>(ConfigDataLoader.class, Instantiator<ConfigDataLoader<?>> instantiator = new Instantiator<>(ConfigDataLoader.class,
(availableParameters) -> { (availableParameters) -> {
@ -75,7 +77,7 @@ class ConfigDataLoaders {
availableParameters.add(BootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapContext.class, bootstrapContext);
availableParameters.add(BootstrapRegistry.class, bootstrapContext); availableParameters.add(BootstrapRegistry.class, bootstrapContext);
}); });
this.loaders = instantiator.instantiate(names); this.loaders = instantiator.instantiate(classLoader, names);
this.resourceTypes = getResourceTypes(this.loaders); this.resourceTypes = getResourceTypes(this.loaders);
} }

@ -77,7 +77,7 @@ class ConfigDataLocationResolvers {
availableParameters.add(BootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapContext.class, bootstrapContext);
availableParameters.add(BootstrapRegistry.class, bootstrapContext); availableParameters.add(BootstrapRegistry.class, bootstrapContext);
}); });
this.resolvers = reorder(instantiator.instantiate(names)); this.resolvers = reorder(instantiator.instantiate(resourceLoader.getClassLoader(), names));
} }
private List<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver<?>> resolvers) { private List<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver<?>> resolvers) {

@ -17,6 +17,7 @@
package org.springframework.boot.env; package org.springframework.boot.env;
import java.util.List; import java.util.List;
import java.util.function.Function;
import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -28,6 +29,7 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener; import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ResourceLoader;
/** /**
* {@link SmartApplicationListener} used to trigger {@link EnvironmentPostProcessor * {@link SmartApplicationListener} used to trigger {@link EnvironmentPostProcessor
@ -47,15 +49,14 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica
private int order = DEFAULT_ORDER; private int order = DEFAULT_ORDER;
private final EnvironmentPostProcessorsFactory postProcessorsFactory; private final Function<ClassLoader, EnvironmentPostProcessorsFactory> postProcessorsFactory;
/** /**
* Create a new {@link EnvironmentPostProcessorApplicationListener} with * Create a new {@link EnvironmentPostProcessorApplicationListener} with
* {@link EnvironmentPostProcessor} classes loaded via {@code spring.factories}. * {@link EnvironmentPostProcessor} classes loaded via {@code spring.factories}.
*/ */
public EnvironmentPostProcessorApplicationListener() { public EnvironmentPostProcessorApplicationListener() {
this(EnvironmentPostProcessorsFactory this((classLoader) -> EnvironmentPostProcessorsFactory.fromSpringFactories(classLoader), new DeferredLogs());
.fromSpringFactories(EnvironmentPostProcessorApplicationListener.class.getClassLoader()));
} }
/** /**
@ -64,11 +65,11 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica
* @param postProcessorsFactory the post processors factory * @param postProcessorsFactory the post processors factory
*/ */
public EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory) { public EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory) {
this(postProcessorsFactory, new DeferredLogs()); this((classloader) -> postProcessorsFactory, new DeferredLogs());
} }
EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory, EnvironmentPostProcessorApplicationListener(
DeferredLogs deferredLogs) { Function<ClassLoader, EnvironmentPostProcessorsFactory> postProcessorsFactory, DeferredLogs deferredLogs) {
this.postProcessorsFactory = postProcessorsFactory; this.postProcessorsFactory = postProcessorsFactory;
this.deferredLogs = deferredLogs; this.deferredLogs = deferredLogs;
} }
@ -96,7 +97,8 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) { private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment(); ConfigurableEnvironment environment = event.getEnvironment();
SpringApplication application = event.getSpringApplication(); SpringApplication application = event.getSpringApplication();
for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) { for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(),
event.getBootstrapContext())) {
postProcessor.postProcessEnvironment(environment, application); postProcessor.postProcessEnvironment(environment, application);
} }
} }
@ -113,8 +115,11 @@ public class EnvironmentPostProcessorApplicationListener implements SmartApplica
this.deferredLogs.switchOverAll(); this.deferredLogs.switchOverAll();
} }
List<EnvironmentPostProcessor> getEnvironmentPostProcessors(ConfigurableBootstrapContext bootstrapContext) { List<EnvironmentPostProcessor> getEnvironmentPostProcessors(ResourceLoader resourceLoader,
return this.postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext); ConfigurableBootstrapContext bootstrapContext) {
ClassLoader classLoader = (resourceLoader != null) ? resourceLoader.getClassLoader() : null;
EnvironmentPostProcessorsFactory postProcessorsFactory = this.postProcessorsFactory.apply(classLoader);
return postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext);
} }
@Override @Override

@ -53,13 +53,13 @@ class ConfigDataLoadersTests {
@Test @Test
void createWhenLoaderHasLogParameterInjectsLog() { void createWhenLoaderHasLogParameterInjectsLog() {
new ConfigDataLoaders(this.logFactory, this.bootstrapContext, new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null,
Arrays.asList(LoggingConfigDataLoader.class.getName())); Arrays.asList(LoggingConfigDataLoader.class.getName()));
} }
@Test @Test
void createWhenLoaderHasDeferredLogFactoryParameterInjectsDeferredLogFactory() { void createWhenLoaderHasDeferredLogFactoryParameterInjectsDeferredLogFactory() {
ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null,
Arrays.asList(DeferredLogFactoryConfigDataLoader.class.getName())); Arrays.asList(DeferredLogFactoryConfigDataLoader.class.getName()));
assertThat(loaders).extracting("loaders").asList() assertThat(loaders).extracting("loaders").asList()
.satisfies(this::containsValidDeferredLogFactoryConfigDataLoader); .satisfies(this::containsValidDeferredLogFactoryConfigDataLoader);
@ -73,7 +73,7 @@ class ConfigDataLoadersTests {
@Test @Test
void createWhenLoaderHasBootstrapParametersInjectsBootstrapContext() { void createWhenLoaderHasBootstrapParametersInjectsBootstrapContext() {
new ConfigDataLoaders(this.logFactory, this.bootstrapContext, new ConfigDataLoaders(this.logFactory, this.bootstrapContext, null,
Arrays.asList(BootstrappingConfigDataLoader.class.getName())); Arrays.asList(BootstrappingConfigDataLoader.class.getName()));
assertThat(this.bootstrapContext.get(String.class)).isEqualTo("boot"); assertThat(this.bootstrapContext.get(String.class)).isEqualTo("boot");
} }
@ -81,7 +81,7 @@ class ConfigDataLoadersTests {
@Test @Test
void loadWhenSingleLoaderSupportsLocationReturnsLoadedConfigData() throws Exception { void loadWhenSingleLoaderSupportsLocationReturnsLoadedConfigData() throws Exception {
TestConfigDataResource location = new TestConfigDataResource("test"); 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())); Arrays.asList(TestConfigDataLoader.class.getName()));
ConfigData loaded = loaders.load(this.context, location); ConfigData loaded = loaders.load(this.context, location);
assertThat(getLoader(loaded)).isInstanceOf(TestConfigDataLoader.class); assertThat(getLoader(loaded)).isInstanceOf(TestConfigDataLoader.class);
@ -90,7 +90,7 @@ class ConfigDataLoadersTests {
@Test @Test
void loadWhenMultipleLoadersSupportLocationThrowsException() { void loadWhenMultipleLoadersSupportLocationThrowsException() {
TestConfigDataResource location = new TestConfigDataResource("test"); 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())); Arrays.asList(LoggingConfigDataLoader.class.getName(), TestConfigDataLoader.class.getName()));
assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location)) assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location))
.withMessageContaining("Multiple loaders found for resource 'test'"); .withMessageContaining("Multiple loaders found for resource 'test'");
@ -99,7 +99,7 @@ class ConfigDataLoadersTests {
@Test @Test
void loadWhenNoLoaderSupportsLocationThrowsException() { void loadWhenNoLoaderSupportsLocationThrowsException() {
TestConfigDataResource location = new TestConfigDataResource("test"); 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())); Arrays.asList(NonLoadableConfigDataLoader.class.getName()));
assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location)) assertThatIllegalStateException().isThrownBy(() -> loaders.load(this.context, location))
.withMessage("No loader found for resource 'test'"); .withMessage("No loader found for resource 'test'");
@ -108,7 +108,7 @@ class ConfigDataLoadersTests {
@Test @Test
void loadWhenGenericTypeDoesNotMatchSkipsLoader() throws Exception { void loadWhenGenericTypeDoesNotMatchSkipsLoader() throws Exception {
TestConfigDataResource location = new TestConfigDataResource("test"); 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())); Arrays.asList(OtherConfigDataLoader.class.getName(), SpecificConfigDataLoader.class.getName()));
ConfigData loaded = loaders.load(this.context, location); ConfigData loaded = loaders.load(this.context, location);
assertThat(getLoader(loaded)).isInstanceOf(SpecificConfigDataLoader.class); assertThat(getLoader(loaded)).isInstanceOf(SpecificConfigDataLoader.class);

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 DefaultBootstrapContext bootstrapContext = spy(new DefaultBootstrapContext());
private EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener( private EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener(
EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class), this.deferredLogs); (classLoader) -> EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class),
this.deferredLogs);
@Test @Test
void createUsesSpringFactories() { void createUsesSpringFactories() {
EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener(); EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener();
assertThat(listener.getEnvironmentPostProcessors(this.bootstrapContext)).hasSizeGreaterThan(1); assertThat(listener.getEnvironmentPostProcessors(null, this.bootstrapContext)).hasSizeGreaterThan(1);
} }
@Test @Test
void createWhenHasFactoryUsesFactory() { void createWhenHasFactoryUsesFactory() {
EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener( EnvironmentPostProcessorApplicationListener listener = new EnvironmentPostProcessorApplicationListener(
EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class)); EnvironmentPostProcessorsFactory.of(TestEnvironmentPostProcessor.class));
List<EnvironmentPostProcessor> postProcessors = listener.getEnvironmentPostProcessors(this.bootstrapContext); List<EnvironmentPostProcessor> postProcessors = listener.getEnvironmentPostProcessors(null,
this.bootstrapContext);
assertThat(postProcessors).hasSize(1); assertThat(postProcessors).hasSize(1);
assertThat(postProcessors.get(0)).isInstanceOf(TestEnvironmentPostProcessor.class); assertThat(postProcessors.get(0)).isInstanceOf(TestEnvironmentPostProcessor.class);
} }

Loading…
Cancel
Save