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.
* @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<String> names) {
ClassLoader classLoader, List<String> names) {
this.logger = logFactory.getLog(getClass());
Instantiator<ConfigDataLoader<?>> 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);
}

@ -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<ConfigDataLocationResolver<?>> reorder(List<ConfigDataLocationResolver<?>> resolvers) {

@ -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<ClassLoader, EnvironmentPostProcessorsFactory> 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<ClassLoader, EnvironmentPostProcessorsFactory> 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<EnvironmentPostProcessor> getEnvironmentPostProcessors(ConfigurableBootstrapContext bootstrapContext) {
return this.postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext);
List<EnvironmentPostProcessor> 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

@ -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);

@ -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<EnvironmentPostProcessor> postProcessors = listener.getEnvironmentPostProcessors(this.bootstrapContext);
List<EnvironmentPostProcessor> postProcessors = listener.getEnvironmentPostProcessors(null,
this.bootstrapContext);
assertThat(postProcessors).hasSize(1);
assertThat(postProcessors.get(0)).isInstanceOf(TestEnvironmentPostProcessor.class);
}

Loading…
Cancel
Save