概述
AutoConfigurationMetadataLoader
是 Spring boot autoconfigure
加载AutoConfigurationMetadata
的内部工具类。
关于应用
// AutoConfigurationImportSelector$AutoConfigurationGroup 代码片段
@Override
public void process(AnnotationMetadata annotationMetadata,
DeferredImportSelector deferredImportSelector) {
Assert.state(
deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)
deferredImportSelector)
.getAutoConfigurationEntry(getAutoConfigurationMetadata(),
annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
// 这里是对 AutoConfigurationMetadataLoader#loadMetadata 的使用
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
源代码解析
源代码版本
Spring Boot 1.5.8.RELEASE
/**
* 用于加载 AutoConfigurationMetadata 的内部工具类
*/
final class AutoConfigurationMetadataLoader {
// 定义要加载的AutoConfigurationMetadata的文件路径
protected static final String PATH = "META-INF/"
+ "spring-autoconfigure-metadata.properties";
private AutoConfigurationMetadataLoader() {
}
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try {
// 找到自动配置元数据属性文件,可能有多个
// 其实就是各个jar包中的文件META-INF\spring-autoconfigure-metadata.properties,
// 其路径类似于spring-boot-autoconfigure-xxx.jar!\META-INF\spring-autoconfigure-metadata.properties
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path));
// 从所发现的配置文件中加载所有的配置信息到一个 properties 对象
Properties properties = new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils
.loadProperties(new UrlResource(urls.nextElement())));
}
// 返回AutoConfigurationMetadata对象,其实现为内部类 PropertiesAutoConfigurationMetadata
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException(
"Unable to load @ConditionalOnClass location [" + path + "]", ex);
}
}
static AutoConfigurationMetadata loadMetadata(Properties properties) {
return new PropertiesAutoConfigurationMetadata(properties);
}
/**
* 基于一个属性文件(properties file)的AutoConfigurationMetadata实现
*/
private static class PropertiesAutoConfigurationMetadata
implements AutoConfigurationMetadata {
private final Properties properties;
PropertiesAutoConfigurationMetadata(Properties properties) {
this.properties = properties;
}
@Override
public boolean wasProcessed(String className) {
return this.properties.containsKey(className);
}
@Override
public Integer getInteger(String className, String key) {
return getInteger(className, key, null);
}
@Override
public Integer getInteger(String className, String key, Integer defaultValue) {
String value = get(className, key);
return (value != null ? Integer.valueOf(value) : defaultValue);
}
@Override
public Set<String> getSet(String className, String key) {
return getSet(className, key, null);
}
@Override
public Set<String> getSet(String className, String key,
Set<String> defaultValue) {
String value = get(className, key);
return (value != null ? StringUtils.commaDelimitedListToSet(value)
: defaultValue);
}
@Override
public String get(String className, String key) {
return get(className, key, null);
}
@Override
public String get(String className, String key, String defaultValue) {
String value = this.properties.getProperty(className + "." + key);
return (value != null ? value : defaultValue);
}
}
}