spring-类SPI机制-SpringFactoriesLoa
2018-05-19 本文已影响38人
Mr_1214
spring的默认扩展放在META-INF/spring.factories下,文件的格式如下:
# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration
SpringFactoriesLoader 默认提供loadFactories,loadFactoryNames,instantiateFactory三个方法,其中loadFactories根据参数factoryClass获取spring.factories下配置的所有实现类实例。loadFactoryNames 根据参数factoryClass获取spring.factories下配置的所有实现类名
instantiateFactory方法是根据实现类名反射获取实现类实例
方法:loadFactories
public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
//获取类的ClassLoader
ClassLoader classLoaderToUse = classLoader;
if(classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
//调用loadFactoryNames获取所有实现类的名称集合
List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
if(logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
}
List<T> result = new ArrayList(factoryNames.size());
Iterator var5 = factoryNames.iterator();
//调用instantiateFactory方法获取给定类名的类实现实例
while(var5.hasNext()) {
String factoryName = (String)var5.next();
result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
}
//对集合排序
AnnotationAwareOrderComparator.sort(result);
return result;
}
通过源码可以看到loadFactories方法主要通过了loadFactoryNames与instantiateFactory完成整个功能的实现。
方法:loadFactoryNames
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
//获取扩展类的全名字符传
String factoryClassName = factoryClass.getName();
try {
// 通过classLoader加载环境中所有jar目录下的META-INF/spring.factories,获取文件集合
Enumeration<URL> urls = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories");
ArrayList result = new ArrayList();
//遍历所有的spring.factories获取给定的factoryClassName(key)
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
//获取factoryClassName下配置的值
String factoryClassNames = properties.getProperty(factoryClassName);
//将factoryClassName下配置的值分割获取集合
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
} catch (IOException var8) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);
}
}
可以看到loadFactoryNames主要完成了spring.factories的查找加载以及对spring.factories的解析等操作,获取到扩展实现的集合后通过反射可以快速的拿到类的实现实例,instantiateFactory方法完成了反射获取实现的过程,不详细分析。