Spring Environment Abstraction

efe813867d1bad136cd0ba4318107977.jpeg

概述

在spring中,properties和profile是Environment abstraction 的两个核心, 作为一个整体模块整合到了Spring container中,Environment abstraction是ApplicationContext的核心功能之一.

profile是关注的不同环境或者说组,比如说我们会用的到的不同环境,dev,beta,prod等,也可能是根据功能来区分不同的组,不同的profile下使用不同的property.

property再熟悉不过,代表了配置文件或者说是资源文件,在所有的应用中都扮演着重要的角色,它的具体表示形式可以有多种多样:

  • properties files

  • JVM system properties

  • system environment variables

Environment API的主要功能就是解析这些不同的属性文件,为应用提供统一的使用方式

c540ab0f916cff46044e0df27e8a563b.jpeg

各组件的职责

Environment API的特性如下:

19fbdd9b46df38dacf7ecfa041636950.jpeg


在spring中,PropertySource是一个抽象类,代表了最小粒度的属性单位,用key-value 一个键值对来表示.

caa06b303b2e527dc1755bd02687ca4f.png

PropertySource代表一个属性,PropertySources代表一组属性,而MutablePropertySources则代表了有先后顺序的多组属性,它们的组织形式如下:

e2a64835653a801a2c2bfeb583f3d3b9.jpeg

Environment作为对所有属性管理者,它的主要功能和逻辑是在其抽象实现类AbstractEnvironement中.

8814e56adfc57bed29687369c34818a7.png

这两个方法的功能通过方法名可知是获取系统变量属性和系统属性(java -jar -Dxxx=aaa).另外有一个重要的方便扩展的方法

customizePropertySources

AbstractEnvironment的各种扩展类是通过这个方法来设置自定义资源的.

2cf929c7938befd80a32df48bb444104.jpeg

StandardEnvironement

32c74bc69b5f2a2e0da823388f71c384.jpeg

而StandardServletEnvironement还加载了Servlet相关的属性

f0ebe15a62d91648a79dadf84430ae60.jpeg

Environement模块的整体组织结构

e5b69299d34808f95e450a73674d860f.jpeg

启动时加载流程

上边分别描述这整个模块中各个类的功能职责,下边从spring mvc启动时的逻辑来串联一下Environment是如何被容器初始化的.

Web容器启动第一步,必须会调用ContextLoader(是通过ContextLoaderListener触发的)

在ContextLoader中的方法中initWebApplicationContext

调用configureAndRefreshWebApplicationContext方法

24e3261c7c49170a7a50ca5c971f8389.jpeg

调用getEnvironment方法

63183521dcb3621432c289dbc77cd3c3.jpeg

dc4649977272b2400cbf2aa28ef3982a.png

createEnvironement

307cf394f9a81b261cfc7ae082ac3f25.png

这样,新创建的StandardServletEnvironment会返回给web容器.

自定义属性文件的加载

到这里,貌似只有环境变量的属性和系统变量的属性有了,那么用户自定义的配置文件是如何加载的呢

PropertySourcesPlaceholderConfigurer这个类是关键

它作为BeanFactoryPostProcessor(bfpp)扩展点的一个实现,在beanFacotry初始化的过程过,作了如下逻辑

203d15ec48ff2f8180c2ce4d36a3d6ec.jpeg

可以看到,第一步,把environment加到propertySources里;第二步,加载localProperty即用户的自定义属性文件,跟进mergeProperteis方法

501918a7e43fe69f5cb5e5cf2be79ccd.jpeg

30b1900bd35313d05842d910c924a4ea.jpeg

注意locations是我们在配置中指定的属性文件路径列表

b91742ed0488f2ecc5155389325ff3ef.jpeg

而PropertiesLoaderUtils.fillProperties(xxx)方法则是具体的读取并解析属性文件的逻辑

a9b478a89127ec5b7c209b590927a939.jpeg

往下不再继续跟,看官可以自己去跟.

到这里简单介绍了spring中的属性文件的表现方式和加载方式,其中涉及的细节较多,一些概念在以往的文章有提到,感兴趣的可查看历史消息.

为了更好的展示代码,不至于格式走样,本文图片较多,非wifi酌情观看,希望文章内容对得起看官们的流量,吼吼

Thx for read

85a92cbc762bff0de1752415cb5167ae.jpeg

SpringAutowired

一个有用的公众号

6ec0622ff7e43d3fc5f3d61f44a8023f.jpeg

长按,识别二维码,加关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值