Loading

Spring系列-1.1 Environment解析

Spring版本:Spring 5.2.9.BUILD-SNAPSHOT

修改过部分源码,但不影响主体流程

Environment简介

Environment是Spring核心框架中定义的一个接口,用来表示整个应用运行时的环境,主要管理应用程序两个方面的内容:profileproperty

profile

一个profile是一组Bean definition的逻辑分组。profile可以简单的等同于环境,比如说平时项目中常见的环境有开发(dev)、测试(stg)和生产(prod),Spring 启动的时候可以设置激活具体的环境。

property

一个应用的属性有很多来源: 属性文件(properties files),JVM系统属性,系统环境变量,JNDI,servlet上下文参数,临时属性对象等。

获取Environment

如果想直接使用Environment对象访问profile状态或者获取属性,可以有两种方式

  • 实现EnvironmentAware接口

  • @Autowired注入一个 Environment 对象

但是基本不这么做,大部分都是通过@Value注解或者在xml配置文件中使用${}进行获取。

继承关系

接口/类
说明
PropertyResolver 接口,抽象对属性源的访问,比如是否包含某个属性,读取属性,解析占位符,将读取到的属性转换成指定类型
Environment 继承自PropertyResolver,对环境属性访问和default/active profile访问的抽象因为继承自PropertyResolver,所以它自然具备PropertyResolver提供的所有能力,对环境属性的访问也正是通过PropertyResolver定义的这些能力
ConfigurablePropertyResolver PropertyResolver接口抽象的属性源访问做了配置方面的增强。比如设置将属性值转换工具,指定占位符前缀后缀
ConfigurableEnvironment 在所继承的接口之上增加了设置defaut/active profile的能力,增加/删除环境对象中属性源的能力
ConfigurableWebEnvironment 向接口ConfigurableEnvironment增强了根据Servlet上下文/配置初始化属性源的能力
AbstractEnvironment Environment抽象基类,实现了ConfigurableEnvironment
StandardEnvironment 针对标准Spring应用的环境,在AbstractEnvironment基础上提供了属性源systemEnvironmentsystemProperties
StandardServletEnvironment 针对标准Spring Servlet Web应用的环境,在StandardEnvironment的基础上增加了servletContextInitParams/servletConfigInitParams/jndiProperties三个属性源

源码解析

入口

public ClassPathXmlApplicationContext(
		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
	// 调用父类构造方法,进行相关的对象创建等操作,包含属性的赋值操作
	// 初始化成员属性
	super(parent);
	//设置应用程序上下文的配置路径
	setConfigLocations(configLocations);
	if (refresh) {
	    refresh();
	}
}

  • 调用super(parent)方法进行相关的对象创建等操作

  • setConfigLocations(configLocations);用于设置配置文件的路径,并处理占位符。

setConfigLocations(configLocations)

	/**
	 * 设置应用程序上下文的配置路径
	 *
	 * Set the config locations for this application context.
	 * <p>If not set, the implementation may use a default as appropriate.
	 */
	public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				// 解析给定路径
				// 处理占位符 spring-${username}.xml
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

resolvePath(String path)

	protected String resolvePath(String path) {
		return getEnvironment().resolveRequiredPlaceholders(path);
	}

getEnvironment()

	@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			this.environment = createEnvironment();
		}
		return this.environment;
	}

createEnvironment()

	protected ConfigurableEnvironment createEnvironment() {
		return new StandardEnvironment();
	}
  • 此时会调用父类的构造方法,父类的构造方法会调到自己实现的customizePropertySources(this.propertySources);
	@Override
	protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(
				new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
		propertySources.addLast(
				new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
	}
  • 此时已经读到系统的相关环境配置信息

posted @ 2022-01-26 15:01  xmz_pc  阅读(343)  评论(0编辑  收藏  举报