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> cache = new
ConcurrentReferenceHashMap<>();
private SpringFactoriesLoader() {
}
/**
* 根据给定的类型加载并实例化工厂的实现类
*/
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 factoryImplementationNames =
loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" +
factoryType.getName() + "] names: " +
factoryImplementationNames);
}
//创建一个存放对象的List
List 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 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>
loadSpringFactories(@Nullable ClassLoader classLoader) {
//根据类加载器从缓存中获取,如果缓存中存在,就直接返回,如果
不存在就去加载
MultiValueMap result =
cache.get(classLoader);
if (result != null) {
return result;
}
try {
//获取所有JAR及classpath路径下的METAINF/spring.factories的路径
Enumeration 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();
}}


 

你可能感兴趣的:(spring,java,spring,boot)