Spring AutoConfigurationMetadataLoader是如何工作的 ?

本文介绍Spring Boot中AutoConfigurationMetadataLoader类的功能及其工作原理。该类负责加载AutoConfigurationMetadata,通过读取特定路径下的属性文件来获取配置信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

AutoConfigurationMetadataLoaderSpring 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);
		}

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值