spring framework源码之SpringFactoriesLoader
SpringFactoriesLoader
查询META-INF/spring.factories的properties配置中指定class对应的所有实现类。
public abstract class SpringFactoriesLoader {
/** The location to look for the factories. Can be present in multiple JAR files. */
private static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
/**
* Loads 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 OrderComparator}.
* @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)
*/
public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
Assert.notNull(factoryClass, "'factoryClass' must not be null");
if (classLoader == null) {
classLoader = SpringFactoriesLoader.class.getClassLoader();
}
List<String> factoryNames = loadFactoryNames(factoryClass, classLoader);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
}
List<T> result = new ArrayList<T>(factoryNames.size());
for (String factoryName : factoryNames) {
result.add(instantiateFactory(factoryName, factoryClass, classLoader));
}
OrderComparator.sort(result);
return result;
}
private static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
List<String> result = new ArrayList<String>();
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
@SuppressWarnings("unchecked")
private static <T> T instantiateFactory(String instanceClassName, Class<T> factoryClass, ClassLoader classLoader) {
try {
Class<?> instanceClass = ClassUtils.forName(instanceClassName, classLoader);
if (!factoryClass.isAssignableFrom(instanceClass)) {
throw new IllegalArgumentException(
"Class [" + instanceClassName + "] is not assignable to [" + factoryClass.getName() + "]");
}
return (T) instanceClass.newInstance();
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate factory class: " + factoryClass.getName(), ex);
}
}
spring framework源码之SpringFactoriesLoader的更多相关文章
- spring framework 源码
spring framework 各版本源码下载地址 现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-pro ...
- Idea搭建spring framework源码环境
spring的源码目前放在github上,https://github.com/spring-projects/spring-framework 一.安装Git 二.安装Gradle gradle为解 ...
- Spring Framework 源码编译导入
预先准备环境 Window 10 JDK环境 List item Gradle 以及其环境变量配置 spring-framework源码(https://gitee.com/mirrors/Sprin ...
- spring framework源码之AnnotationConfigApplicationContext
AnnotationConfigApplicationContext 内部使用了AnnotatedBeanDefinitionReader:ClassPathBeanDefinitionScanner ...
- 走进Spring Boot源码学习之路和浅谈入门
Spring Boot浅聊入门 **本人博客网站 **IT小神 www.itxiaoshen.com Spring Boot官网地址:https://spring.io/projects/spring ...
- 精尽Spring MVC源码分析 - 调式环境搭建
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- spring事务源码研读1
转载摘录自:Spring事务源码分析(一)Spring事务入门 有时为了保证一些操作要么都成功,要么都失败,这就需要事务来保证. 传统的jdbc事务如下: @Test public void test ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
- Spring AOP 源码分析系列文章导读
1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...
随机推荐
- PythonCrashCourse 第九章习题
创建一个名为Restaurant 的类,其方法__init__() 设置两个属性: restaurant_name 和cuisine_type 创建一个名为describe _restaurant ( ...
- CentOS7上lvm分区调整(resize2fs: Bad magic number in super-block while trying to open ...)
问题描述:根目录空间占用率100% 首先用传统resize2fs方式调整分区: resize2fs -p /dev/mapper/centos-home 50Gresize2fs 1.42.9 (28 ...
- python numpy数组操作2
数组的四则运算 在numpy模块中,实现四则运算的计算既可以使用运算符号,也可以使用函数,具体如下例所示: #加法运算 import numpy as npmath = np.array([98,83 ...
- Java多线程_Master-Worker设计模式
Master-Worker模式是常用的并行模式之一,它的核心思想是:系统由Master进程和Worker进程两类进程协同工作,Master负责接收和分配任务,Wroker负责处理子任务.当各个Work ...
- 软件工程第二次作业(Junit和GoogleTest)
使用Eclipse的Junit框架进行单元测试 一.前言 我的电脑因为以前学过安卓开发,已经安装好了eclipse,看了邹欣老师的博客,博客上讲的的非常详细,所以在进行的过程中遇到困难,基本都能解决. ...
- 焦大:做seo需要的三心二意
http://www.wocaoseo.com/thread-92-1-1.html 读过一些外国人写的教程之后,愈发觉得国外人写的教程甚是有趣,比起国内学习的课本来,真是不可同日而语. ...
- 接口测试中GET方法的获取
今天在这里给大家介绍一下get方法,其实这些方法大家可以看一下源码里面的介绍只需要在代码中输入: import requests help(requests) 就可以看到带有示例的解释: 现在我们来完 ...
- element UI 上传文件成功后 - 清空文件
request({ url: '/jiekou', method: 'post', data }).then(res => { this.$message({ type: 'success', ...
- 【C#】Random类中构造方法、时间种子与随机数序列的关系
Random类 构造函数 1) Random random = new Random(); // 无参数构造函数使用系统时钟生成其种子值 然而,系统时钟取值范围有限,因此在小规模计算中,可能无法使用不 ...
- chrome设置跨域访问
1.新建目录 /usr/local/opt/myChromData 2.输入命令行 open -n /Applications/Google\ Chrome.app/ --args --disable ...