本节将对ConfigDataEnvironmentContributors进行分析,该对象的基础定义具体代码如下:
class ConfigDataEnvironmentContributors implements Iterable<ConfigDataEnvironmentContributor> { private final ConfigDataEnvironmentContributor root; private final ConfigurableBootstrapContext bootstrapContext; }
在这段基础定义代码中可以发现ConfigDataEnvironmentContributors也是一个迭代器接口的实现类,在ConfigDataEnvironmentContributors中有以下两个成员变量:
(1)成员变量root表示环境配置数据提供者;
(2)成员变量bootstrapContext表示引导上下文。
在ConfigDataEnvironmentContributors中上述两个成员变量都需要通过构造函数进行设置,ConfigDataEnvironmentContributors的构造函数有两个,具体代码如下:
了解构造函数和成员变量后下面将对核心方法withProcessedImports进行分析,具体处理代码如下:
在withProcessedImports方法中主要的处理流程如下:
(1)确定导入阶段(ImportPhase)。
(2)定义结果集合。
(3)获取一个需要处理的环境配置提供者(ConfigDataEnvironmentContributor),下文简称提供者。
(4)如果提供者对象为空将返回对象本身作为处理结果。
(5)当提供者的类型是UNBOUND_IMPORT时进行如下操作:
①从提供者中获取属性源集合对象;
②创建占位符解析器,创建绑定对象,绑定对象是属性源和占位符解析器之间的关系;
③通过提供者对象提供的withBoundProperties方法将绑定对象中的数据解析成ConfigData-EnvironmentContributor;
④将ConfigDataEnvironmentContributor转换成ConfigDataEnvironmentContributors,并赋值给结果集合。
(6)创建配置数据解析上下文(ContributorConfigDataLocationResolverContext),创建配置数据加载上下文(ConfigDataLoaderContext)。
(7)从提供者中获取配置数据地址集合。
(8)通过ConfigDataImporter将数据地址集合中的数据进行解析,这里处理核心需要使用到ConfigDataLoader和ConfigDataLocationResolver。
(9)创建当前贡献者和它的子贡献者的组合对象,类型是ConfigDataEnvironmentContributor,在这个对象中子贡献者是imported中的数据。
(10)创建ConfigDataEnvironmentContributors并将其赋值给结果集合对象。
在上述处理流程中提及了两个接口,第一个是ConfigDataLoaderContext,第二个是Config-DataLocationResolverContext,这两个接口的实现类是在ConfigDataEnvironmentContributors中通过内部类进行实现的。下面将对ConfigDataLoaderContext的实现类ContributorDataLoader-Context进行分析,关于该对象的详细代码如下:
private static class ContributorDataLoaderContext implements ConfigDataLoaderContext { private final ConfigDataEnvironmentContributors contributors; ContributorDataLoaderContext(ConfigDataEnvironmentContributors contributors) { this.contributors = contributors; } public ConfigurableBootstrapContext getBootstrapContext() { return this.contributors.getBootstrapContext(); } }
在ContributorDataLoaderContext中关于ConfigDataLoaderContext的实现是从提供者中获取引导上下文将其作为返回值,整体处理十分清晰。下面将对ConfigDataLocationResolverContext的实现类ContributorConfigDataLocationResolverContext进行分析,有关ContributorConfigData LocationResolverContext成员变量可查看表5-4。
表5-4 ContributorConfigDataLocationResolverContext成员变量
上述成员变量中除了binder以外都会通过构造函数进行初始化,关于binder的数据操作由getBinder方法提供,具体处理代码如下:
public Binder getBinder() { Binder binder = this.binder; if (binder == null) { binder = this.contributors.getBinder(this.activationContext); this.binder = binder; } return binder; }
在withProcessedImports方法中其他的处理流程复杂度不是很高,在withProcessedImports的处理过程中更多用到的操作实际上是对象的转换,这里进行对象的转换并非Spring中的Converter接口,而是多个方法之间的组合调度从而达到对象转换。