Spring源码--Enviroment的设计体系

前言

Enviroment对象用来保证一些系统变量,环境边等等信息,那么再Spring中是在什么时候常见起来的呢,它的继承体系又是如何的呢?我们开发过程中能否对其进行DIY呢?本文将回答这些问题。

分析过程

首先通过Spring的启动过程看Environment最初是在哪里被使用到的,一路追进去,看this这个构造方法

AbstractApplicationContext的构造方法
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
   this();
   setParent(parent);
}
public AbstractApplicationContext() {
   // 资源模式处理器,用来解析系统运行需要的资源,比如配置文件,xml文件
   this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
   return new PathMatchingResourcePatternResolver(this);
}

setParent,这里是空

	public void setParent(@Nullable ApplicationContext parent) {
		this.parent = parent;
		if (parent != null) {
			Environment parentEnvironment = parent.getEnvironment();
			if (parentEnvironment instanceof ConfigurableEnvironment) {
				getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
			}
		}
	}
这里有个getEnvironment方法,点进去看看
AbstractApplicationContext里面的getEnviroment方法,懒加载的方式去获取
public ConfigurableEnvironment getEnvironment() {
   if (this.environment == null) {
      this.environment = createEnvironment();
   }
   return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
   return new StandardEnvironment();
}

如果直接点构造方法,实际上啥也看不到,这里又个技巧,这个需要在父类的构造方法中打断点!否则是看不到构造过程的,这样就可以看到,实际上它调用到了父类的默认构造器。

Enviroment体系

属性解析器,这个里面真正解析处理字符串是在一个PropertyPlaceholderHelper之中进行的。它处理的数据是存在在PropertySources这个接口之中。

属性源,对属性的封装,MutablePropertiesSources里面又一个LIst,这个List存储的就是PropertiesSource的设计。PropertySource又很多具体的实现,可以这么理解,Enviroment叫Resolver去干活,Resolver里面去找Source,在Source里面实际上存储的是Map结构。

PropertiySource的继承结构

 

说几个重要的PropertySource,比如MapPropertySource就是对简单的PropertySource进行了很多的扩展,这个类里面是通过map作为Source来存储属性,进行属性的读取。        

Stadard的创建是使用了模板方法设计模式,子类重写了父类的方法,父类构造方法调用了子类实现的方法。

系统环境
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
系统属性
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
自定义属性源
​​​​​​​@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()));
}

StandardServletEnvironment扩展StanrdEnvironment,这个里面对属性值进行了扩展。新增了一些PropertySource。

总结

  1. Environment是一个包工头,指挥Resolver干活,Resolver又指挥Helper干活,体现了分层的思想,也体现了单一职责的思想,通过组合的方式实现松耦合的效果。
  2. 扩展性的体现在PropertieySource这个接口以及MutablePropertiesSources,通过for循环遍历Sources去读取。
  3. 如果我们要管理一些属性可以怎么做呢,同样的,可以读取一个文件,然后将文件读取为map结构,放在一个MapPropertySource里面,对这个类进行扩展,就可以实现一个对属性进行自定义管理的属性类了,还是比较方便的,同样的,我们甚至可以将这个作为Environment,add到Enviroment里面的MutablePropertySources的那个List中去,这样我们甚至可以DIY的去将一些属性添加进去管理,然后如果Spring框架的API进行扩区。
  4. 对于设计方面的思考,单一职责,面向接口,可扩展性体现的淋漓尽致,模板方法模式等等,MutablePropertySource的设计等等都值得借鉴。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值