通过前文已读取到7个后置处理器,逐一查看
首先是org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor
—————— postProcessEnvironment start
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
RandomValuePropertySource.addToEnvironment(environment, this.logger);
}
——————— addToEnvironment start
org.springframework.boot.env.RandomValuePropertySource
public static final String RANDOM_PROPERTY_SOURCE_NAME = "random";
static void addToEnvironment(ConfigurableEnvironment environment, Log logger) {
MutablePropertySources sources = environment.getPropertySources();
PropertySource<?> existing = sources.get(RANDOM_PROPERTY_SOURCE_NAME);
if (existing != null) {
logger.trace("RandomValuePropertySource already present");
return;
}
RandomValuePropertySource randomSource = new RandomValuePropertySource(RANDOM_PROPERTY_SOURCE_NAME);
if (sources.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) != null) {
sources.addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, randomSource);
}
else {
sources.addLast(randomSource);
}
logger.trace("RandomValuePropertySource add to Environment");
}
获取属性资源集合实例
MutablePropertySources sources = environment.getPropertySources();
获取已存在的随机属性资源实例
PropertySource<?> existing = sources.get(RANDOM_PROPERTY_SOURCE_NAME);
判断随机属性资源实例是否存在
if (existing != null) {
logger.trace("RandomValuePropertySource already present");
return;
}
此时实例不存在
创建属性资源实例
RandomValuePropertySource randomSource = new RandomValuePropertySource(RANDOM_PROPERTY_SOURCE_NAME);
添加属性资源实例
if (sources.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) != null) {
sources.addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, randomSource);
}
else {
sources.addLast(randomSource);
}
若存在名为systemEnvironment的资源,则将随机资源放在其后面;否则放在最后
——————— addToEnvironment end
总结org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor
创建随机属性资源实例并添加至环境实例中
—————— postProcessEnvironment end
接着是org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
—————— postProcessEnvironment start
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String sourceName = StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
PropertySource<?> propertySource = environment.getPropertySources().get(sourceName);
if (propertySource != null) {
replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());
}
}
获取系统环境属性资源实例
String sourceName = StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
PropertySource<?> propertySource = environment.getPropertySources().get(sourceName);
替换系统环境属性资源实例
if (propertySource != null) {
replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());
}
获取环境前缀
application.getEnvironmentPrefix()
——————— getEnvironmentPrefix start
org.springframework.boot.SpringApplication
private String environmentPrefix;
public String getEnvironmentPrefix() {
return this.environmentPrefix;
}
——————— getEnvironmentPrefix end
默认无前缀
替换
——————— replacePropertySource start
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
@SuppressWarnings("unchecked")
private void replacePropertySource(ConfigurableEnvironment environment, String sourceName,
PropertySource<?> propertySource, String environmentPrefix) {
Map<String, Object> originalSource = (Map<String, Object>) propertySource.getSource();
SystemEnvironmentPropertySource source = new OriginAwareSystemEnvironmentPropertySource(sourceName,
originalSource, environmentPrefix);
environment.getPropertySources().replace(sourceName, source);
}
获取原始的属性资源
Map<String, Object> originalSource = (Map<String, Object>) propertySource.getSource();
创建新的属性资源实例
SystemEnvironmentPropertySource source = new OriginAwareSystemEnvironmentPropertySource(sourceName,
originalSource, environmentPrefix);
替换属性资源实例
environment.getPropertySources().replace(sourceName, source);
——————— replacePropertySource end
总结org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
将原先名为systemEnvironment的属性资源实例由org.springframework.core.env.SystemEnvironmentPropertySource
变更为org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource
—————— postProcessEnvironment end
接着是org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
—————— postProcessEnvironment start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.stream().map(JsonPropertyValue::get).filter(Objects::nonNull).findFirst()
.ifPresent((v) -> processJson(environment, v));
}
获取属性资源集合实例
MutablePropertySources propertySources = environment.getPropertySources();
流处理集合
propertySources.stream().map(JsonPropertyValue::get).filter(Objects::nonNull).findFirst()
.ifPresent((v) -> processJson(environment, v));
获取json属性值
.map(JsonPropertyValue::get)
——————— get start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor$JsonPropertyValue
private static final String[] CANDIDATES = { SPRING_APPLICATION_JSON_PROPERTY,
SPRING_APPLICATION_JSON_ENVIRONMENT_VARIABLE };
static JsonPropertyValue get(PropertySource<?> propertySource) {
for (String candidate : CANDIDATES) {
Object value = propertySource.getProperty(candidate);
if (value instanceof String && StringUtils.hasLength((String) value)) {
return new JsonPropertyValue(propertySource, candidate, (String) value);
}
}
return null;
}
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
public static final String SPRING_APPLICATION_JSON_PROPERTY = "spring.application.json";
public static final String SPRING_APPLICATION_JSON_ENVIRONMENT_VARIABLE = "SPRING_APPLICATION_JSON";
从属性资源中寻找名为 spring.application.json或 SPRING_APPLICATION_JSON的值
Object value = propertySource.getProperty(candidate);
创建json属性值实例并返回
if (value instanceof String && StringUtils.hasLength((String) value)) {
return new JsonPropertyValue(propertySource, candidate, (String) value);
}
查看构造方法
———————— JsonPropertyValue start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor$JsonPropertyValue
private final PropertySource<?> propertySource;
private final String propertyName;
private final String json;
JsonPropertyValue(PropertySource<?> propertySource, String propertyName, String json) {
this.propertySource = propertySource;
this.propertyName = propertyName;
this.json = json;
}
———————— JsonPropertyValue end
——————— get end
过滤空实例
.filter(Objects::nonNull)
处理json
.findFirst().ifPresent((v) -> processJson(environment, v))
——————— processJson start
private void processJson(ConfigurableEnvironment environment, JsonPropertyValue propertyValue) {
JsonParser parser = JsonParserFactory.getJsonParser();
Map<String, Object> map = parser.parseMap(propertyValue.getJson());
if (!map.isEmpty()) {
addJsonPropertySource(environment, new JsonPropertySource(propertyValue, flatten(map)));
}
}
获取解析器
JsonParser parser = JsonParserFactory.getJsonParser();
———————— getJsonParser start
org.springframework.util.ClassUtils.JsonParserFactory
public static JsonParser getJsonParser() {
if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {
return new JacksonJsonParser();
}
if (ClassUtils.isPresent("com.google.gson.Gson", null)) {
return new GsonJsonParser();
}
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
return new YamlJsonParser();
}
return new BasicJsonParser();
}
———————— getJsonParser end
将json字符串解析为Map实例
Map<String, Object> map = parser.parseMap(propertyValue.getJson());
将map的值扁平化
flatten(map)
———————— flatten start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
private Map<String, Object> flatten(Map<String, Object> map) {
Map<String, Object> result = new LinkedHashMap<>();
flatten(null, result, map);
return result;
}
创建集合
Map<String, Object> result = new LinkedHashMap<>();
处理并添加至集合
flatten(null, result, map);
————————— flatten start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
private void flatten(String prefix, Map<String, Object> result, Map<String, Object> map) {
String namePrefix = (prefix != null) ? prefix + "." : "";
map.forEach((key, value) -> extract(namePrefix + key, result, value));
}
指定前缀
String namePrefix = (prefix != null) ? prefix + "." : "";
遍历集合,提取值
map.forEach((key, value) -> extract(namePrefix + key, result, value));
—————————— extract start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
@SuppressWarnings("unchecked")
private void extract(String name, Map<String, Object> result, Object value) {
if (value instanceof Map) {
if (CollectionUtils.isEmpty((Map<?, ?>) value)) {
result.put(name, value);
return;
}
flatten(name, result, (Map<String, Object>) value);
}
else if (value instanceof Collection) {
if (CollectionUtils.isEmpty((Collection<?>) value)) {
result.put(name, value);
return;
}
int index = 0;
for (Object object : (Collection<Object>) value) {
extract(name + "[" + index + "]", result, object);
index++;
}
}
else {
result.put(name, value);
}
}
- 若当前值为
Map
,递归处理
if (value instanceof Map) {
if (CollectionUtils.isEmpty((Map<?, ?>) value)) {
result.put(name, value);
return;
}
flatten(name, result, (Map<String, Object>) value);
}
- 若当前值为
Collection
,遍历处理
else if (value instanceof Collection) {
if (CollectionUtils.isEmpty((Collection<?>) value)) {
result.put(name, value);
return;
}
int index = 0;
for (Object object : (Collection<Object>) value) {
extract(name + "[" + index + "]", result, object);
index++;
}
}
- 否则仅添加至结果集合
else {
result.put(name, value);
}
—————————— extract end
————————— flatten end
返回集合
return result;
———————— flatten end
由上述代码可知flatten
方法将值为多层级的原map
扁平化处理,返回值均为单层级的新map
创建json属性资源实例
———————— JsonPropertySource start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor$JsonPropertySource
private final JsonPropertyValue propertyValue;
JsonPropertySource(JsonPropertyValue propertyValue, Map<String, Object> source) {
super(SPRING_APPLICATION_JSON_PROPERTY, source);
this.propertyValue = propertyValue;
}
查看父类构造方法
————————— MapPropertySource start
org.springframework.core.env.MapPropertySource
public MapPropertySource(String name, Map<String, Object> source) {
super(name, source);
}
查看父类构造方法
—————————— MapPropertySource start
org.springframework.core.env.EnumerablePropertySource
public EnumerablePropertySource(String name, T source) {
super(name, source);
}
其父类为org.springframework.core.env.PropertySource
,前文已看过
—————————— MapPropertySource end
————————— MapPropertySource end
———————— JsonPropertySource end
即创建名为spring.application.json的实例
———————— flatten end
添加json属性资源实例至环境
———————— addJsonPropertySource start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
private void addJsonPropertySource(ConfigurableEnvironment environment, PropertySource<?> source) {
MutablePropertySources sources = environment.getPropertySources();
String name = findPropertySource(sources);
if (sources.contains(name)) {
sources.addBefore(name, source);
}
else {
sources.addFirst(source);
}
}
获取属性资源集合
MutablePropertySources sources = environment.getPropertySources();
查找属性资源名称
String name = findPropertySource(sources);
————————— findPropertySource start
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
private static final String SERVLET_ENVIRONMENT_CLASS = "org.springframework.web."
+ "context.support.StandardServletEnvironment";
private static final Set<String> SERVLET_ENVIRONMENT_PROPERTY_SOURCES = new LinkedHashSet<>(
Arrays.asList(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
private String findPropertySource(MutablePropertySources sources) {
if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null)) {
PropertySource<?> servletPropertySource = sources.stream()
.filter((source) -> SERVLET_ENVIRONMENT_PROPERTY_SOURCES.contains(source.getName())).findFirst()
.orElse(null);
if (servletPropertySource != null) {
return servletPropertySource.getName();
}
}
return StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
}
判断是否存在web环境类
if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null))
即org.springframework.web.context.support.StandardServletEnvironment
由于未引入web相关包,此时不存在
此处有个疑问,SERVLET_ENVIRONMENT_PROPERTY_SOURCES
可以正常初始化,并有3个值(jndiProperties、servletContextInitParams、servletConfigInitParams)。这些值怎么来的?知道的朋友麻烦告诉我原因
返回系统属性资源名称
return StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
————————— findPropertySource end
———————— addJsonPropertySource end
——————— processJson end
总结org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
查找环境实例中配置的json值,根据值创建属性资源实例并添加至环境实例中
—————— postProcessEnvironment end
接着是org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
—————— postProcessEnvironment start
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
if (CloudPlatform.CLOUD_FOUNDRY.isActive(environment)) {
Properties properties = new Properties();
JsonParser jsonParser = JsonParserFactory.getJsonParser();
addWithPrefix(properties, getPropertiesFromApplication(environment, jsonParser), "vcap.application.");
addWithPrefix(properties, getPropertiesFromServices(environment, jsonParser), "vcap.services.");
MutablePropertySources propertySources = environment.getPropertySources();
if (propertySources.contains(CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME)) {
propertySources.addAfter(CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME,
new PropertiesPropertySource("vcap", properties));
}
else {
propertySources.addFirst(new PropertiesPropertySource("vcap", properties));
}
}
}
判断cloud foundry是否活动
CloudPlatform.CLOUD_FOUNDRY.isActive(environment)
——————— CLOUD_FOUNDRY start
org.springframework.boot.cloud.CloudPlatform
CLOUD_FOUNDRY {
@Override
public boolean isDetected(Environment environment) {
return environment.containsProperty("VCAP_APPLICATION") || environment.containsProperty("VCAP_SERVICES");
}
}
——————— CLOUD_FOUNDRY end
——————— isActive start
org.springframework.boot.cloud.CloudPlatform
private static final String PROPERTY_NAME = "spring.main.cloud-platform";
public boolean isActive(Environment environment) {
String platformProperty = environment.getProperty(PROPERTY_NAME);
return isEnforced(platformProperty) || (platformProperty == null && isDetected(environment));
}
此时platformProperty
为null
判断是否执行
isEnforced(platformProperty)
———————— isEnforced start
org.springframework.boot.cloud.CloudPlatform
private boolean isEnforced(String platform) {
return name().equalsIgnoreCase(platform);
}
———————— isEnforced end
判断是否发现
isDetected(environment)
即环境实例是否包括属性VCAP_APPLICATION或VCAP_SERVICES
——————— isActive end
总结org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
是对Cloud Foundry
平台的支持,若环境实例中发现相关配置的值,则根据值创建属性资源实例并添加至环境实例中
—————— postProcessEnvironment end