|
|
|
@ -36,15 +36,17 @@ import org.springframework.util.StringUtils;
@@ -36,15 +36,17 @@ import org.springframework.util.StringUtils;
|
|
|
|
|
/** |
|
|
|
|
* General purpose factory loading mechanism for internal use within the framework. |
|
|
|
|
* |
|
|
|
|
* <p>The {@code SpringFactoriesLoader} loads and instantiates factories of a given type |
|
|
|
|
* from "META-INF/spring.factories" files. The file should be in {@link Properties} format, |
|
|
|
|
* where the key is the fully qualified interface or abstract class name, and the value |
|
|
|
|
* is a comma-separated list of implementation class names. For instance: |
|
|
|
|
* <p>{@code SpringFactoriesLoader} {@linkplain #loadFactories loads} and instantiates |
|
|
|
|
* factories of a given type from {@value #FACTORIES_RESOURCE_LOCATION} files which |
|
|
|
|
* may be present in multiple JAR files in the classpath. The {@code spring.factories} |
|
|
|
|
* file must be in {@link Properties} format, where the key is the fully qualified |
|
|
|
|
* name of the interface or abstract class, and the value is a comma-separated list of |
|
|
|
|
* implementation class names. For example: |
|
|
|
|
* |
|
|
|
|
* <pre class="code">example.MyService=example.MyServiceImpl1,example.MyServiceImpl2</pre> |
|
|
|
|
* |
|
|
|
|
* where {@code MyService} is the name of the interface, and {@code MyServiceImpl1} and |
|
|
|
|
* {@code MyServiceImpl2} are the two implementations. |
|
|
|
|
* where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1} |
|
|
|
|
* and {@code MyServiceImpl2} are two implementations. |
|
|
|
|
* |
|
|
|
|
* @author Arjen Poutsma |
|
|
|
|
* @author Juergen Hoeller |
|
|
|
@ -53,18 +55,26 @@ import org.springframework.util.StringUtils;
@@ -53,18 +55,26 @@ import org.springframework.util.StringUtils;
|
|
|
|
|
*/ |
|
|
|
|
public abstract class SpringFactoriesLoader { |
|
|
|
|
|
|
|
|
|
/** The location to look for the factories. Can be present in multiple JAR files. */ |
|
|
|
|
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; |
|
|
|
|
|
|
|
|
|
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The location to look for factories. |
|
|
|
|
* <p>Can be present in multiple JAR files. |
|
|
|
|
*/ |
|
|
|
|
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Load the factory implementations of the given type from the default location, |
|
|
|
|
* using the given class loader. |
|
|
|
|
* <p>The returned factories are ordered in accordance with the {@link AnnotationAwareOrderComparator}. |
|
|
|
|
* Load and instantiate the factory implementations of the given type from |
|
|
|
|
* {@value #FACTORIES_RESOURCE_LOCATION}, using the given class loader. |
|
|
|
|
* <p>The returned factories are sorted in accordance with the {@link AnnotationAwareOrderComparator}. |
|
|
|
|
* <p>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 classLoader the ClassLoader to use for loading (can be {@code null} to use the default) |
|
|
|
|
* @see #loadFactoryNames |
|
|
|
|
* @throws IllegalArgumentException if any factory implementation class cannot |
|
|
|
|
* be loaded or if an error occurs while instantiating any factory |
|
|
|
|
*/ |
|
|
|
|
public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) { |
|
|
|
|
Assert.notNull(factoryClass, "'factoryClass' must not be null"); |
|
|
|
@ -84,6 +94,16 @@ public abstract class SpringFactoriesLoader {
@@ -84,6 +94,16 @@ public abstract class SpringFactoriesLoader {
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 classLoader the ClassLoader to use for loading resources; can be |
|
|
|
|
* {@code null} to use the default |
|
|
|
|
* @see #loadFactories |
|
|
|
|
* @throws IllegalArgumentException if an error occurs while loading factory names |
|
|
|
|
*/ |
|
|
|
|
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { |
|
|
|
|
String factoryClassName = factoryClass.getName(); |
|
|
|
|
try { |
|
|
|
|