
在spring中,properties和profile是Environment abstraction 的两个核心, 作为一个整体模块整合到了Spring container中,Environment abstraction是ApplicationContext的核心功能之一.
profile是关注的不同环境或者说组,比如说我们会用的到的不同环境,dev,beta,prod等,也可能是根据功能来区分不同的组,不同的profile下使用不同的property.
property再熟悉不过,代表了配置文件或者说是资源文件,在所有的应用中都扮演着重要的角色,它的具体表示形式可以有多种多样:
JVM system properties
Environment API的主要功能就是解析这些不同的属性文件,为应用提供统一的使用方式

Environment API的特性如下:

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

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

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

这两个方法的功能通过方法名可知是获取系统变量属性和系统属性(java -jar -Dxxx=aaa).另外有一个重要的方便扩展的方法
customizePropertySources
AbstractEnvironment的各种扩展类是通过这个方法来设置自定义资源的.

StandardEnvironement

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

Environement模块的整体组织结构

上边分别描述这整个模块中各个类的功能职责,下边从spring mvc启动时的逻辑来串联一下Environment是如何被容器初始化的.
Web容器启动第一步,必须会调用ContextLoader(是通过ContextLoaderListener触发的)
在ContextLoader中的方法中initWebApplicationContext
调用configureAndRefreshWebApplicationContext方法

调用getEnvironment方法


createEnvironement

这样,新创建的StandardServletEnvironment会返回给web容器.
到这里,貌似只有环境变量的属性和系统变量的属性有了,那么用户自定义的配置文件是如何加载的呢
PropertySourcesPlaceholderConfigurer这个类是关键
它作为BeanFactoryPostProcessor(bfpp)扩展点的一个实现,在beanFacotry初始化的过程过,作了如下逻辑

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


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

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

往下不再继续跟,看官可以自己去跟.
到这里简单介绍了spring中的属性文件的表现方式和加载方式,其中涉及的细节较多,一些概念在以往的文章有提到,感兴趣的可查看历史消息.
为了更好的展示代码,不至于格式走样,本文图片较多,非wifi酌情观看,希望文章内容对得起看官们的流量,吼吼
Thx for read

SpringAutowired
一个有用的公众号

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