本节将对ConfigDataLoaders进行分析,在该对象中存储了ConfigDataLoader的集合,ConfigDataLoaders的具体定义代码如下:
class ConfigDataLoaders { private final Log logger; // 配置数据加载器集合 private final List<ConfigDataLoader<?>> loaders; // 资源类型集合 private final List<Class<?>> resourceTypes; }
在这个对象中还需要关注成员变量loaders和resourceTypes的初始化,详细代码如下:
ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext, List<String> names) { this.logger = logFactory.getLog(getClass()); Instantiator<ConfigDataLoader<?>> instantiator = new Instantiator<>(ConfigDataLoader.class, (availableParameters) -> { availableParameters.add(Log.class, logFactory::getLog); availableParameters.add(DeferredLogFactory.class, logFactory); availableParameters.add(ConfigurableBootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapContext.class, bootstrapContext); availableParameters.add(BootstrapRegistry.class, bootstrapContext); }); this.loaders = instantiator.instantiate(names); this.resourceTypes = getResourceTypes(this.loaders); }
通过上述代码可以发现成员变量loaders和resourceTypes都需要依赖参数names,这里需要向外搜索外部调用时names的传参,对外调用方法只有一处,具体代码如下:
ConfigDataLoaders(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext) { this(logFactory, bootstrapContext, SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, null)); }
在这段代码中,可以发现ConfigDataLoaders会获取spring.factories文件中键为org.springframework.boot.context.config.ConfigDataLoader的数据,在Spring Boot中该对象的数据信息如下:
org.springframework.boot.context.config.ConfigDataLocationResolver=\ org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\ org.springframework.boot.context.config.StandardConfigDataLocationResolver
上述代码中的ConfigTreeConfigDataLocationResolver和StandardConfigDataLocationResolver就是names的数据信息,确定了names的数据信息后查看Instantiator中提供的实例化方法,详细代码如下:
在上述代码中关于names元素的实例化操作具体操作如下:
(1)获取构造函数;
(2)获取构造函数的参数值列表,当参数值不为空的情况下通过构造函数对象的newInstance方法将其实例化。
注意,在完成names中元素的实例化后会进行排序操作。在ConfigDataLoaders中除了关注成员变量和构造函数以外还需要关注load方法,详细处理代码如下:
在该方法中会根据不同的资源对象找到不同的配置数据记载器,再通过配置数据记载器将资源进行解析。