SpringCloud学习笔记(二)-Config配置
Config分为三个部分:ConfigServer
ConfigClient
配置仓库
一、ConfigServer如何提供配置
SpringCloud中申明ConfigServer时,通过@EnableConfigServer开启ConfigServer配置。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ConfigServerConfiguration.class)
public @interface EnableConfigServer {
}
而EnableConfigServer中又引入了ConfigServerConfiguration,申明了内部类Maker,并装配为一个Bean。
@Configuration
public class ConfigServerConfiguration {
class Marker {}
@Bean
public Marker enableConfigServerMarker() {
return new Marker();
}
}
通过ConfigServerConfiguration.Maker又开启了ConfigServerAutoConfiguration配置(通过@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
开启,在装配Maker时会执行该配置)。
@Configuration
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class,
ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class, TransportConfiguration.class })
public class ConfigServerAutoConfiguration {
}
通过@Import引入了6个重要的配置类
EnvironmentRepositoryConfiguration
:环境仓库配置,是关键的配置类
CompositeConfiguration
:混合配置,用于多环境下配置资源的加载
ResourceRepositoryConfiguration
:资源仓库相关配置
ConfigServerEncryptionConfiguration
:ConfigServer加密相关配置
ConfigServerMvcConfiguration
:对外暴露的MVC相关配置
TransportConfiguration
:运行transport命令前,配置回调
EnvironmentRepositoryConfiguration的配置
环境仓库的配置又细分为JDBC
、Vault
、svn
、Native(本地)
、Git
等配置,默认是Git配置.
多种配置方式,最终都会被装配成EnvironmentRepository,以本地配置装配为例看下类图结构:
![](https://img.haomeiwen.com/i10173293/5a882b205dc93cd3.png)
1. NativeEnvironmentRepository本地配置加载
2. GitRepositoryConfiguration Git配置加载
等等...
二、ConfigClient的调用
ConfigServer在启动的时候会申明一个REST接口(EnvironmentController)当有配置客户端查询请求时,通过调用EnvironmentRepository.findOne方法返回一个Environment对象,客户端反序列化得到Environment对象。
@RequestMapping("/{name}/{profiles:.*[^-].*}")
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
return labelled(name, profiles, null);
}
@RequestMapping("/{name}/{profiles}/{label:.*}")
public Environment labelled(@PathVariable String name, @PathVariable String profiles,
@PathVariable String label) {
if (label != null && label.contains("(_)")) {
// "(_)" is uncommon in a git branch name, but "/" cannot be matched
// by Spring MVC
label = label.replace("(_)", "/");
}
Environment environment = this.repository.findOne(name, profiles, label);
return environment;
}
findOne根据配置信息解析过滤配置属性,封装为Environment对象返回给客户端。
public class NativeEnvironmentRepository{
//在ConfigClient启动时调用
//config:文件名称,即在Configclient中配置的config.name
//profile:ConfigClient中配置的config.profile
@Override
public Environment findOne(String config, String profile, String label) {
//启动一个SpringBoot内部微型工程,用于加载配置文件
SpringApplicationBuilder builder = new SpringApplicationBuilder(
PropertyPlaceholderAutoConfiguration.class);
ConfigurableEnvironment environment = getEnvironment(profile);
builder.environment(environment);
builder.web(false).bannerMode(Mode.OFF);
if (!logger.isDebugEnabled()) {
// Make the mini-application startup less verbose
builder.logStartupInfo(false);
}
String[] args = getArgs(config, profile, label);
// Explicitly set the listeners (to exclude logging listener which would change
// log levels in the caller)
builder.application()
.setListeners(Arrays.asList(new ConfigFileApplicationListener()));
ConfigurableApplicationContext context = builder.run(args);
environment.getPropertySources().remove("profiles");
try {
//过滤出所有配置
return clean(new PassthruEnvironmentRepository(environment).findOne(config,
profile, label));
}
finally {
context.close();
}
}
}
返回的Environment对象也可以直接通过在地址栏输入http连接看到
![](https://img.haomeiwen.com/i10173293/f4c60a4144692422.png)