本节将对ConfigDataLocationResolver进行分析,该接口主要用于解析ConfigDataLocation对象,将其转换成配置资源对象(ConfigDataResource),关于ConfigDataLocationResolver的定义代码如下:
public interface ConfigDataLocationResolver<R extends ConfigDataResource> { // 判断是否可以处理 boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location); // 解析资源 List<R> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException; // 解析资源 default List<R> resolveProfileSpeci fi c(ConfigDataLocationResolverContext context, ConfigDataLocation location, Profiles profiles) throws ConfigDataLocationNotFoundException { return Collections.emptyList(); } }
在ConfigDataLocationResolver中定义了以下三个方法:
(1)方法isResolvable用于判断是否可以处理;
(2)方法resolve用于解析资源;
(3)方法resolveProfileSpecific用于解析资源。
在Spring Boot中关于ConfigDataLocationResolver有三个实现类,分别是SubversionConfig-DataLocationResolver、StandardConfigDataLocationResolver和ConfigTreeConfigDataLocationResolver,本节后续将对这三个类进行分析。
本节将对SubversionConfigDataLocationResolver进行分析,详细代码如下:
在isResolvable方法中会判断是否是"svn:"开头,如果是则可以处理,否则不能处理。在resolve方法中会获取spring.svn.server.certificate的数据类型,具体数据类型是String,绑定完成后会创建SubversionConfigDataResource再将其转换成Collections。
本节将对StandardConfigDataLocationResolver进行分析,在该对象中主要关注StandardConfigDataLocationResolver成员变量,详细说明见表5-1。
表5-1 StandardConfigDataLocationResolver成员变量
在StandardConfigDataLocationResolver中主要关注resolve方法,具体处理代码如下:
public List<StandardConfigDataResource> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) throws ConfigDataNotFoundException { // 1. 获取StandardConfigDataResource集合 // 2. 解析 return resolve(getReferences(context, location)); }
在上述方法中主要的处理流程有两个:
(1)获取StandardConfigDataResource集合;
(2)将获取的StandardConfigDataResource集合进一步解析。
上述处理流程主要关注第(2)个处理,在这个操作过程中会依赖成员变量resourceLoader来进一步解析。上述流程可以理解为递归获取文件夹下的所有内容。
本节将对ConfigTreeConfigDataLocationResolver进行分析,在该对象中最重要的方法是resolve,详细处理代码如下:
private List<ConfigTreeConfigDataResource> resolve(ConfigDataLocationResolverContext context, String location) throws IOException { Assert.isTrue(location.endsWith("/"), () -> String.format("Config tree location '%s' must end with '/'", location)); // 判断是否匹配,不匹配直接创建ConfigTreeConfigDataResource并将其转换成Collections 返回 if (!this.resourceLoader.isPattern(location)) { return Collections.singletonList(new ConfigTreeConfigDataResource(location)); } // 获取location中出现的资源对象 Resource[] resources = this.resourceLoader.getResources(location, ResourceType.DIRECTORY); List<ConfigTreeConfigDataResource> resolved = new ArrayList<>(resources.length); for (Resource resource :resources) { // 获取资源对象的文件路径,转换成ConfigTreeConfigDataResource resolved.add(new ConfigTreeConfigDataResource(resource.getFile().toPath())); } return resolved; }
在resolve方法中主要的处理操作流程如下:
(1)判断是否匹配,不匹配直接创建ConfigTreeConfigDataResource并将其转换成Collections返回;
(2)获取location中出现的资源对象,将获取的资源对象集合进行转换,转换成Config-TreeConfigDataResource类型。