前话
通过前文笔者得知,cloud config server提供了多种方式的外部源配置获取。当然也暴露了接口供外界调用,通用的方式是通过JMX接口来调用;笔者则比较关注其MVC方式,这也是本文分析的重点
ConfigServerAutoConfiguration
该自动配置类将server所涉及的功能安排的明明白白的。笔者先贴下它的源码
@Configuration
// 只有使用了@EnableConfigServer注解才会生效
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class,
ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class })
public class ConfigServerAutoConfiguration {
}
导入的类有五个,按照步骤来稍微分析下
EnvironmentRepositoryConfiguration-环境仓库配置
此类在前文已经提过了,也就是提供多种方式的获取远程配置,比如GIT、SVN、VAULT等,具体可查阅前文
CompositeConfiguration-多环境仓库Bean创建
与前者的EnvironmentRepository环境仓库搭配使用,内部源码也很简单
private List<EnvironmentRepository> environmentRepos = new ArrayList<>();
@Bean
@Primary
@ConditionalOnBean(SearchPathLocator.class)
public SearchPathCompositeEnvironmentRepository searchPathCompositeEnvironmentRepository() {
return new SearchPathCompositeEnvironmentRepository(environmentRepos);
}
@Bean
@Primary
@ConditionalOnMissingBean(SearchPathLocator.class)
public CompositeEnvironmentRepository compositeEnvironmentRepository() {
return new CompositeEnvironmentRepository(environmentRepos);
}
@Autowired
public void setEnvironmentRepos(List<EnvironmentRepository> repos) {
this.environmentRepos = repos;
}
上述的SearchPathLocator接口一般指代的是环境仓库类,比如JGitEnvironmentRepository。采用了适配器方式进行了整合
ResourceRepositoryConfiguration-文件资源仓库配置
内部的源码也很简单,就是创建了一个ResourceRepository对象,用于读取符合条件的任一单个PropertySource文件
@Configuration
@EnableConfigurationProperties(ConfigServerProperties.class)
@ConditionalOnMissingBean(ResourceRepository.class)
public class ResourceRepositoryConfiguration {
// GenericResourceRepository对象创建
@Bean
@ConditionalOnBean(SearchPathLocator.class)
public ResourceRepository resourceRepository(SearchPathLocator service) {
return new GenericResourceRepository(service);
}
}
其会在ResourceController类中有所提及,下文分析。有兴趣的可以去分析其源码,其内部有个findOne()方法用于找寻符合条件的任一文件
public interface ResourceRepository {
/**
**
** @param name 与搜寻路径搭配使用,见前文
** @param profile 与搜寻路径搭配使用,见前文
** @param label 与搜寻路径搭配使用,见前文
** @param path 文件具体名,比如application.properties
**
**
*/
Resource findOne(String name, String profile, String label, String path);
}
ConfigServerEncryptionConfiguration-加解密功能
对外暴露了EncryptionController,用于加解密参数。具体的读者可自行分析
@Configuration
public class ConfigServerEncryptionConfiguration {
@Autowired(required=false)
private TextEncryptorLocator encryptor;
@Autowired
private ConfigServerProperties properties;
@Bean
public EncryptionController encryptionController() {
EncryptionController controller = new EncryptionController(this.encryptor);
controller.setDefaultApplicationName(this.properties.getDefaultApplicationName());
controller.setDefaultProfile(this.properties.getDefaultProfile());
return controller;
}
}
ConfigServerMvcConfiguration-MVC配置
MVC的对外功能,主要是由此类来提供的,其创建了两个Controller:EnvironmentController和ResourceController。前者主要暴露符合条件的所有PropertySource,后者则暴露符合条件的任一个PropertySource。
@Configuration
@ConditionalOnWebApplication
// 复写WebMvcConfigurer接口
public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter {
@Autowired(required = false)
private EnvironmentEncryptor environmentEncryptor;
@Autowired(required = false)
private ObjectMapper objectMapper = new ObjectMapper();
// 增加对properties/yml/yaml文件的输出支持
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.mediaType("properties", MediaType.valueOf("text/plain"));
configurer.mediaType("yml", MediaType.valueOf("text/yaml"));
configurer.mediaType("yaml", MediaType.valueOf("text/yaml"));
}
// 针对环境属性
@Bean
public EnvironmentController environmentController(EnvironmentRepository envRepository, ConfigServerProperties server) {
EnvironmentController controller = new EnvironmentController(encrypted(envRepository, server), this.objectMapper);
controller.setStripDocumentFromYaml(server.isStripDocumentFromYaml());
controller.setAcceptEmpty(server.isAcceptEmpty());
return controller;
}
// 针对文件,与GenericResourceRepository搭配使用
@Bean
@ConditionalOnBean(ResourceRepository.class)
public ResourceController resourceController(ResourceRepository repository, EnvironmentRepository envRepository, ConfigServerProperties server) {
ResourceController controller = new ResourceController(repository,
encrypted(envRepository, server));
return controller;
}
}
暴露的HTTP接口本文就不赘述了,读者可自行查阅,附上些许例子
Environment接口
小结
最后以一张图来表明springcloud config server的工作原理,方便后期回顾整理