在前文提到了Spring Boot中支持的配置文件类型包括yml(yaml)、properties和xml,对于这三种配置文件的读取还需要依赖ConfigDataLoader来进行整体处理,本节将对ConfigData Loader做简单介绍,该接口的详细代码如下:
public interface ConfigDataLoader<R extends ConfigDataResource> { // 判断是否可以加载 default boolean isLoadable(ConfigDataLoaderContext context, R resource) { return true; } // 加载资源 ConfigData load(ConfigDataLoaderContext context, R resource) throws IOException, ConfigDataResourceNotFoundException; }
在ConfigDataLoader中定义了以下两个方法:
(1)方法isLoadable用于判断是否可以进行加载,默认允许加载;
(2)方法load用于进行资源加载。
在接口定义中还标记了资源对象的基础类型是ConfigDataResource,关于ConfigData-Resource的定义如下:
public abstract class ConfigDataResource { // 是否可选 private final boolean optional; }
这里需要对ConfigDataResource抽象类的实现类进行说明,这些实现类会和ConfigData-Loader的实现类做出配合处理。在Spring Boot中ConfigDataResource的子类有如下三个:
(1)对象SubversionConfigDataResource用于存储服务证书;
(2)对象ConfigTreeConfigDataResource用于存储文件地址;
(3)对象StandardConfigDataResource用于存储标准配置。
下面对上述三个对象进行说明,关于SubversionConfigDataResource的定义代码如下:
class SubversionConfigDataResource extends ConfigDataResource { // 地址 private final String location; // 服务证书 private final SubversionServerCertificate serverCertificate; }
在SubversionConfigDataResource中有两个成员变量:
(1)成员变量location用于存储文件地址;
(2)成员变量serverCertificate是一个String变量,用于存储证书内容。
下面对ConfigTreeConfigDataResource进行说明,该对象的详细代码如下:
public class ConfigTreeConfigDataResource extends ConfigDataResource { // 文件地址 private final Path path; }
在ConfigTreeConfigDataResource中只有一个成员变量path,用于存储文件地址。最后对StandardConfigDataResource进行说明,该对象的详细代码如下:
public class StandardConfigDataResource extends ConfigDataResource { // 标准配置数据 private final StandardConfigDataReference reference; // 资源对象 private final Resource resource; // 是否为空目录 private final boolean emptyDirectory; }
在StandardConfigDataResource中有以下三个成员变量:
(1)成员变量reference表示标准配置数据;
(2)成员变量resource表示资源对象;
(3)成员变量emptyDirectory表示是否为空目录。
在上述三个成员变量中最关键的是reference,它的类型是StandardConfigDataReference,关于StandardConfigDataReference的代码定义如下:
class StandardConfigDataReference { // 数据地址对象 private final ConfigDataLocation configDataLocation; // 资源地址 private final String resourceLocation; // 目录 private final String directory; // profile标志 private final String profile; // 属性源加载器 private final PropertySourceLoader propertySourceLoader; }
在StandardConfigDataReference中有以下5个成员变量:
(1)成员变量configDataLocation表示数据地址对象;
(2)成员变量resourceLocation表示资源地址路径;
(3)成员变量directory表示目录名称;
(4)成员变量profile表示profile标志;
(5)成员变量propertySourceLoader表示属性源加载器。
至此,对于抽象类ConfigDataResource的相关内容已经介绍完毕,下面将开始对ConfigDataLoader相关的实现类进行分析。
本节将对SubversionConfigDataLoader进行说明,与SubversionConfigDataLoader匹配的资源对象(ConfigDataResource)是SubversionConfigDataResource,也就是证书相关的一些内容。对于SubversionConfigDataLoader的分析主要从load方法出发,详细的处理代码如下:
public ConfigData load(ConfigDataLoaderContext context, SubversionConfigDataResource resource) throws IOException, ConfigDataLocationNotFoundException { // 获取引导上下文并从中注册证书数据 context.getBootstrapContext().registerIfAbsent(SubversionServerCertificate. class, InstanceSupplier.of(resource.getServerCertificate())); // 从引导上下文中获取SubversionClient SubversionClient client = context.getBootstrapContext().get(SubversionClient. class); // 通过SubversionClient将资源地址中的数据进行读取 String loaded = client.load(resource.getLocation()); // 将读取到的数据转换成MapPropertySource PropertySource<?> propertySource = new MapPropertySource("svn", Collections.singletonMap("svn", loaded)); // 将转换成PropertySource类型的数据再转换成ConfigData类型 return new ConfigData(Collections.singleton(propertySource)); }
在load方法中主要的处理流程如下:
(1)获取引导上下文并从中注册证书数据;
(2)通过引导上下文获取SubversionClient;
(3)通过SubversionClient将资源对象(SubversionConfigDataResource)中的路径进行读取;
(4)将读取的数据先转换成MapPropertySource类型,再将其转换成ConfigData类型并返回。
在load方法中可以发现,需要从引导上下文中获取,关于该对象的设置流程也是一个值得研究的问题。SubversionClient的设置是由SubversionConfigDataLoader的构造方法进行的,具体处理代码如下:
SubversionConfigDataLoader(BootstrapRegistry bootstrapRegistry) { // 注册SubversionClient实例 bootstrapRegistry.registerIfAbsent(SubversionClient.class, this:: createSubversionClient); // 添加关闭监听器 bootstrapRegistry.addCloseListener(closeListener); }
在上述代码中主要处理以下两件事:
(1)通过引导注册接口注册SubversionClient实例;
(2)为引导注册器添加关闭监听器。
这里关于引导注册器中的关闭监听器对应的处理方法如下:
private static void onBootstrapContextClosed(BootstrapContextClosedEvent event) { event.getApplicationContext().getBeanFactory().registerSingleton("subversionClient", event.getBootstrapContext().get(SubversionClient.class)); }
在关闭引导注册器上下文时会将SubversionClient实例放入应用上下文中。
本节将对ConfigTreeConfigDataLoader进行分析,关于ConfigTreeConfigDataLoader的代码信息如下:
在上述代码中关于load的处理操作流程如下:
(1)获取资源对象中的path对象;
(2)检查资源是否存在,如果资源不存在则抛出异常;
(3)创建ConfigTreePropertySource用于存储path对象,创建成功后将其转换为ConfigData对象。
在ConfigTreeConfigDataLoader中关于资源的加载操作不是很复杂,主要思想是进行资源对象的获取和多次类型转换,从而达到ConfigData对象的创建。
本节将对StandardConfigDataLoader进行分析,关于StandardConfigDataLoader的代码信息如下:
在上述代码中关于load的处理操作流程如下:
(1)判断资源是否是一个空目录,如果是则返回空结果;
(2)判断资源对象是否为空,如果为空则抛出异常;
(3)从资源对象中获取标准配置数据对象(StandardConfigDataReference);
(4)将标准配置数据中存储的资源地址转换成实际的资源对象;
(5)通过标准配置对象中的属性源加载器将资源进行解析得到属性源集合;
(6)将属性源集合转换成ConfigData对象返回。
在Spring Boot中关于application.yml(yaml)或者application.properties的解析操作都将由该方法进行核心处理。下面将采用spring-boot-smoke-test-web-ui项目中的application.properties进行说明,具体代码如下:
spring.thymeleaf.cache:false server.tomcat.access_log_enabled:true server.tomcat.basedir:target/tomcat
接下来查看resource数据信息,详细如图5-1所示。
图5-1 resource数据信息
在Resource中存储了application.properties的路径信息。通过reference.getPropertySource-Loader().load(name,originTrackedResource)代码执行后处理结果如图5-2所示。
从图5-2中可以发现,在application.properties文件中的数据已经被成功读取,至此对于StandardConfigDataLoader的分析告一段落。
图5-2 load方法执行结果