spring工厂类

SpringFactoriesLoader
SpringFactoriesLoader类的主要作用是通过类路径下的METAINF/spring.factories文件获取工厂类接口的实现类,初始化并保存在缓存
中,以供Springboot启动过程中各个阶段的调用。Spring的自动化配置功
能,也与此息息相关。
SpringFactoriesLoader 工厂加载机制是 Spring 内部提供的一个约定俗
成的加载方式,只需要在模块的 META-INF/spring.factories 文件中,以
Properties 类型(即 key-value 形式)配置,就可以将相应的实现类注入
Spirng 容器中。
Properties 类型格式:

key:value
key:是全限定名(抽象类|接口)
value:是实现类,多个实现类通过逗号进行分隔

spring boot 类路径下: META-INFO/spring.factories

# Logging Systems
org.springframework.boot.logging.LoggingSystemFactory=\
........
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=
\
......
org.springframework.boot.web.context.ServerPortInfoApplica
tionContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
......
org.springframework.boot.liquibase.LiquibaseServiceLocator
ApplicationListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
......
org.springframework.boot.reactor.DebugAgentEnvironmentPost
Processor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
......

loadFactoryNames
 读取classpath上所有的jar包中的所有META-INF/spring.factories属性文
件,找出其中定义的匹配类型factoryClass的工厂类,然后返回这些工厂类
的名字列表,注意是全限定名。
loadFactories
读取classpath上所有的jar包中的所有META-INF/spring.factories属性文
件,找出其它定义的匹配类型factoryClass的工厂类,然后创建每个工厂类
的对象/实例,并返回这些工厂类对象/实例的列表。

public final class SpringFactoriesLoader {
//文件位置,可以存在多个JAR文件中
public static final String FACTORIES_RESOURCE_LOCATION
= "META-INF/spring.factories";
//用来缓存MultiValueMap对象
private static final Map<ClassLoader,
MultiValueMap<String, String>> cache = new
ConcurrentReferenceHashMap<>();
private SpringFactoriesLoader() {
}
/**
* 根据给定的类型加载并实例化工厂的实现类
*/
public static <T> List<T> loadFactories(Class<T>
factoryType, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryType, "'factoryType' must
not be null");
//获取类加载器
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse =
SpringFactoriesLoader.class.getClassLoader();
}
//加载类的全限定名
List<String> factoryImplementationNames =
loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" +
factoryType.getName() + "] names: " +
factoryImplementationNames);
}
//创建一个存放对象的List
List<T> result = new ArrayList<>
(factoryImplementationNames.size());
for (String factoryImplementationName :
factoryImplementationNames) {
//实例化Bean,并将Bean放入到List集合中
result.add(instantiateFactory(factoryImplementationName,
factoryType, classLoaderToUse));
}
//对List中的Bean进行排序
AnnotationAwareOrderComparator.sort(result);
return result;
}
/**
* 根据给定的类型加载类路径的全限定名
*/
public static List<String> loadFactoryNames(Class<?>
factoryType, @Nullable ClassLoader classLoader) {
//获取名称
String factoryTypeName = factoryType.getName();
//加载并获取所有META-INF/spring.factories中的value
return
loadSpringFactories(classLoader).getOrDefault(factoryTypeN
ame, Collections.emptyList());
}
private static Map<String, List<String>>
loadSpringFactories(@Nullable ClassLoader classLoader) {
//根据类加载器从缓存中获取,如果缓存中存在,就直接返回,如果
不存在就去加载
MultiValueMap<String, String> result =
cache.get(classLoader);
if (result != null) {
return result;
}
try {
//获取所有JAR及classpath路径下的METAINF/spring.factories的路径
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION
));
result = new LinkedMultiValueMap<>();
//遍历所有的META-INF/spring.factories的路径
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new
UrlResource(url);
//将META-INF/spring.factories中的key value
加载为Prpperties对象
Properties properties =
PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry :
properties.entrySet()) {
//key名称
String factoryTypeName = ((String)
entry.getKey()).trim();
}}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值