Use resource loader's class loader in config loading

Previously, classes involved in config loading used a variety of
potentially different class loaders when calling SpringFactoriesLoader.
Some classes would use their own class loader and others would use null
which results in SpringFactoriesLoader's class loader being used.

This commit updates the config loading classes to consistently use the
resource loader's class loader.

Fixes gh-26126
This commit is contained in:
Andy Wilkinson 2021-05-13 13:25:47 +01:00
parent f92510e39d
commit 89b5ece9b4
5 changed files with 11 additions and 7 deletions

View File

@ -152,7 +152,7 @@ class ConfigDataEnvironment {
this.additionalProfiles = additionalProfiles;
this.environmentUpdateListener = (environmentUpdateListener != null) ? environmentUpdateListener
: ConfigDataEnvironmentUpdateListener.NONE;
this.loaders = new ConfigDataLoaders(logFactory, bootstrapContext);
this.loaders = new ConfigDataLoaders(logFactory, bootstrapContext, resourceLoader.getClassLoader());
this.contributors = createContributors(binder);
}

View File

@ -51,9 +51,11 @@ 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}
*/
ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext) {
this(logFactory, bootstrapContext, SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, null));
ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
ClassLoader classLoader) {
this(logFactory, bootstrapContext, SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, classLoader));
}
/**

View File

@ -54,7 +54,7 @@ class ConfigDataLocationResolvers {
ConfigDataLocationResolvers(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
Binder binder, ResourceLoader resourceLoader) {
this(logFactory, bootstrapContext, binder, resourceLoader, SpringFactoriesLoader
.loadFactoryNames(ConfigDataLocationResolver.class, ConfigDataLocationResolver.class.getClassLoader()));
.loadFactoryNames(ConfigDataLocationResolver.class, resourceLoader.getClassLoader()));
}
/**

View File

@ -316,7 +316,7 @@ public class ConfigFileApplicationListener implements EnvironmentPostProcessor,
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader(null);
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
getClass().getClassLoader());
this.resourceLoader.getClassLoader());
}
void load() {

View File

@ -37,6 +37,7 @@ import org.springframework.boot.context.config.ConfigDataEnvironmentContributors
import org.springframework.boot.context.properties.bind.BindException;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.mock.env.MockPropertySource;
@ -84,8 +85,9 @@ class ConfigDataEnvironmentContributorsTests {
this.environment = new MockEnvironment();
this.binder = Binder.get(this.environment);
ConfigDataLocationResolvers resolvers = new ConfigDataLocationResolvers(this.logFactory, this.bootstrapContext,
this.binder, null);
ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext);
this.binder, new DefaultResourceLoader(getClass().getClassLoader()));
ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext,
getClass().getClassLoader());
this.importer = new ConfigDataImporter(this.logFactory, ConfigDataNotFoundAction.FAIL, resolvers, loaders);
this.activationContext = new ConfigDataActivationContext(CloudPlatform.KUBERNETES, null);
}