config是一个微服务配置组件,为微服务提供集中化的配置管理服务。config包含服务端和客户端,客户端在启动服务时从服务端拉取配置信息,服务端响应客户端的请求提供具体的配置。本章分析config组件配置信息的拉取过程
1、config服务端
服务端响应请求的过程比较简单,主要由spring-cloud-config-server包下EnvironmentController负责
@RestController
@RequestMapping(method = {RequestMethod.GET},path = {"${spring.cloud.config.server.prefix:}"}
)
public class EnvironmentController {/*** 根据环境类型和文件名拉取信息**/ @RequestMapping(path = {"/{name}/{profiles:.*[^-].*}"},produces = {"application/json"})public Environment defaultLabel(@PathVariable String name, @PathVariable String profiles) {return this.getEnvironment(name, profiles, (String)null, false);}public Environment getEnvironment(String name, String profiles, String label, boolean includeOrigin) {name = this.normalize(name);label = this.normalize(label);Environment environment = this.repository.findOne(name, profiles, label, includeOrigin);if (this.acceptEmpty || environment != null && !environment.getPropertySources().isEmpty()) {return environment;} else {throw new EnvironmentNotFoundException("Profile Not found");}}}
getEnvironment方法会调用EnvironmentRepository接口的实现类来查找环境信息,类似dao层
public interface EnvironmentRepository {Environment findOne(String application, String profile, String label);default Environment findOne(String application, String profile, String label, boolean includeOrigin) {return this.findOne(application, profile, label);}
}
2、config客户端
springboot在启动时会调用applyInitializers方法,这个方法会遍历ApplicationContextInitializer接口的实现类并调用它们的initialize方法
【SpringBoot】SpringBoot源码解析第二章 SpringBoot的run方法-CSDN博客
protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");initializer.initialize(context);}
}
config客户端中的PropertySourceBootstrapConfiguration类实现了ApplicationContextInitializer接口,它的工作就是拉取远程的配置信息并与本地信息整合
public void initialize(ConfigurableApplicationContext applicationContext) {...while(true) {Collection source;do {do {...PropertySourceLocator locator = (PropertySourceLocator)var5.next();// 拉取远程配置信息source = locator.locateCollection(environment);} while(source == null);} while(source.size() == 0);...}}
ConfigServicePropertySourceLocator是PropertySourceLocator接口的实现类,查看它的locate方法
@Retryable(interceptor = "configServerRetryInterceptor"
)
public PropertySource<?> locate(Environment environment) {...for(int var11 = 0; var11 < var10; ++var11) {String label = var9[var11];...// 发送请求org.springframework.cloud.config.environment.Environment result = this.getRemoteEnvironment(restTemplate, properties, label.trim(), state);...}
}private Environment getRemoteEnvironment(RestTemplate restTemplate, ConfigClientProperties properties, String label, String state) {String path = "/{name}/{profile}";String name = properties.getName();String profile = properties.getProfile();String token = properties.getToken();...response = restTemplate.exchange(uri + path, HttpMethod.GET, entity, org.springframework.cloud.config.environment.Environment.class, args);...}
}
locate方法发送具体的请求,拉取过来的远程信息会被整合入本地
3、总结
config服务端负责响应请求,config客户端在服务启动时会从服务端拉取配置信息