运行SpringApplication四

通过前文已读取到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.jsonSPRING_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));
}

此时platformPropertynull

判断是否执行
isEnforced(platformProperty)

———————— isEnforced start

org.springframework.boot.cloud.CloudPlatform

private boolean isEnforced(String platform) {
	return name().equalsIgnoreCase(platform);
}

———————— isEnforced end

判断是否发现
isDetected(environment)

即环境实例是否包括属性VCAP_APPLICATIONVCAP_SERVICES
——————— isActive end
总结org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor是对Cloud Foundry平台的支持,若环境实例中发现相关配置的值,则根据值创建属性资源实例并添加至环境实例中
—————— postProcessEnvironment end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值