diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
index e50ee46e4ce..0d84bca9b98 100644
--- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
+++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -83,25 +83,25 @@ public final class SpringFactoriesLoader {
*
The returned factories are sorted through {@link AnnotationAwareOrderComparator}.
*
If a custom instantiation strategy is required, use {@link #loadFactoryNames}
* to obtain all registered factory names.
- * @param factoryClass the interface or abstract class representing the factory
+ * @param factoryType the interface or abstract class representing the factory
* @param classLoader the ClassLoader to use for loading (can be {@code null} to use the default)
* @throws IllegalArgumentException if any factory implementation class cannot
* be loaded or if an error occurs while instantiating any factory
* @see #loadFactoryNames
*/
- public static List loadFactories(Class factoryClass, @Nullable ClassLoader classLoader) {
- Assert.notNull(factoryClass, "'factoryClass' must not be null");
+ public static List loadFactories(Class factoryType, @Nullable ClassLoader classLoader) {
+ Assert.notNull(factoryType, "'factoryType' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
- List factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
+ List factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
- logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
+ logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
}
- List result = new ArrayList<>(factoryNames.size());
- for (String factoryName : factoryNames) {
- result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
+ List result = new ArrayList<>(factoryImplementationNames.size());
+ for (String factoryImplementationName : factoryImplementationNames) {
+ result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
}
AnnotationAwareOrderComparator.sort(result);
return result;
@@ -111,15 +111,15 @@ public final class SpringFactoriesLoader {
* Load the fully qualified class names of factory implementations of the
* given type from {@value #FACTORIES_RESOURCE_LOCATION}, using the given
* class loader.
- * @param factoryClass the interface or abstract class representing the factory
+ * @param factoryType the interface or abstract class representing the factory
* @param classLoader the ClassLoader to use for loading resources; can be
* {@code null} to use the default
* @throws IllegalArgumentException if an error occurs while loading factory names
* @see #loadFactories
*/
- public static List loadFactoryNames(Class> factoryClass, @Nullable ClassLoader classLoader) {
- String factoryClassName = factoryClass.getName();
- return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
+ public static List loadFactoryNames(Class> factoryType, @Nullable ClassLoader classLoader) {
+ String factoryTypeName = factoryType.getName();
+ return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
@@ -138,9 +138,9 @@ public final class SpringFactoriesLoader {
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry, ?> entry : properties.entrySet()) {
- String factoryClassName = ((String) entry.getKey()).trim();
- for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
- result.add(factoryClassName, factoryName.trim());
+ String factoryTypeName = ((String) entry.getKey()).trim();
+ for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
+ result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
@@ -154,17 +154,19 @@ public final class SpringFactoriesLoader {
}
@SuppressWarnings("unchecked")
- private static T instantiateFactory(String instanceClassName, Class factoryClass, ClassLoader classLoader) {
+ private static T instantiateFactory(String factoryImplementationName, Class factoryType, ClassLoader classLoader) {
try {
- Class> instanceClass = ClassUtils.forName(instanceClassName, classLoader);
- if (!factoryClass.isAssignableFrom(instanceClass)) {
+ Class> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
+ if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
throw new IllegalArgumentException(
- "Class [" + instanceClassName + "] is not assignable to [" + factoryClass.getName() + "]");
+ "Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
}
- return (T) ReflectionUtils.accessibleConstructor(instanceClass).newInstance();
+ return (T) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();
}
catch (Throwable ex) {
- throw new IllegalArgumentException("Unable to instantiate factory class: " + factoryClass.getName(), ex);
+ throw new IllegalArgumentException(
+ "Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]",
+ ex);
}
}
diff --git a/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java b/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java
index 56939b9cfc1..3ed12f0a2cb 100644
--- a/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java
+++ b/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 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.
@@ -19,7 +19,9 @@ package org.springframework.core.io.support;
import java.lang.reflect.Modifier;
import java.util.List;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import static org.junit.Assert.*;
@@ -28,9 +30,13 @@ import static org.junit.Assert.*;
*
* @author Arjen Poutsma
* @author Phillip Webb
+ * @author Sam Brannen
*/
public class SpringFactoriesLoaderTests {
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
@Test
public void loadFactoriesInCorrectOrder() {
List factories = SpringFactoriesLoader.loadFactories(DummyFactory.class, null);
@@ -39,17 +45,20 @@ public class SpringFactoriesLoaderTests {
assertTrue(factories.get(1) instanceof MyDummyFactory2);
}
- @Test(expected = IllegalArgumentException.class)
- public void loadInvalid() {
- SpringFactoriesLoader.loadFactories(String.class, null);
- }
-
@Test
public void loadPackagePrivateFactory() {
List factories =
SpringFactoriesLoader.loadFactories(DummyPackagePrivateFactory.class, null);
assertEquals(1, factories.size());
- assertTrue((factories.get(0).getClass().getModifiers() & Modifier.PUBLIC) == 0);
+ assertFalse(Modifier.isPublic(factories.get(0).getClass().getModifiers()));
+ }
+
+ @Test
+ public void attemptToLoadFactoryOfIncompatibleType() {
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("Unable to instantiate factory class [org.springframework.core.io.support.MyDummyFactory1] for factory type [java.lang.String]");
+
+ SpringFactoriesLoader.loadFactories(String.class, null);
}
}