Environment环境
一般我喜欢叫它Spring的环境抽象,该“实例”代表着上下文的运行环境,主要包含如下三部分内容:
- PropertySource:属性源。key-value属性对抽象。环境内会有多个属性源,使用MutablePropertySources来组织
- PropertyResolver:属性解析器。用于解析相应key的value,比如你熟悉的PropertySourcesPropertyResolver就是实现
- Profile:配置(资料里翻译为剖面、侧面,也是阔仪的)。只有激活的配置profile的组件/配置才会注册到Spring容器,类似于maven中profile
Environment抽象Spring一共提供了三个实现类:
- 用于非web环境的:StandardEnvironment
- 用于web环境的:StandardServletEnvironment和StandardReactiveWebEnvironment,他俩均为StandardEnvironment的子类。
- 需要注意的是:后者StandardReactiveWebEnvironment由Spring Boot提供,而非Spring Framework源生
这里小带一句:很多同学把属性和配置傻傻分不清楚,其实他俩就是Properties(k-v)和Profile概念上的差异,但口头上经常混用,一般可认为讲的是同一回事,但是你心里必须清楚哈。毕竟和专业人士聊起来的时候,还是需要这些细节掌握的
尴尬爆料:今天猛然发现,之前好多文章里我把Environment单词写错了,写为了Enviroment,特此提醒各位不要“学我”哦
属性源
Spring通过Environment建模Spring应用运行的环境,这其中最为重要的非属性源莫属。一个属性源就是一个PropertySource,它可以来自任意地方,如常用的有:
- systemProperties -> 来自 system.getProperties()
- systemEnvironment -> system.getenv()
- random -> 来自一个Random对象,可用于生成随机数(SB提供)
- applicationConfig: [classpath:/application.yaml] -> SB主配置,这个太常见了吧
- …
属性源的优先级决定了配置的优先级。Spring Boot对其外部化配置优先级有文档说明:Spring Boot外部化配置
我该如何记忆Spring Boot属性优先级?
答案:不要记。精确答案:不要强记,因为“记不住”的。我见过不少(非常多)小伙伴一遇到需要考虑Spring Boot属性优先级问题时,整头就大了,立马拿出自己的小本本,又或者去度娘里查,或许那会还在内心里骂自己:怎么老是记不住呢?甚至质疑自己:是不是真的老了?
我说的此现象,你是否躺枪?授之以鱼不如授之以渔,对于这种“高难度、易出错”的知识点,浮于表面总觉浅,掌握其本质才是永恒。当然我这里不会去详讲Spring Boot这块的知识点,但我还是呕心沥血的整理出一堆截图,告诉你为何你强行记忆是记不住的(如果你是“天才”你就可以跳过本文了):
附:Spring Boot所有版本外部化配置一览
Spring Boot从它的1.0.x版本到现在的2.2.x版本,对于外部化配置的支持几乎是一直在变化/增加的,这种不确定性也无疑在一定程度上增加了我们记忆的难度。下面我从其官方文档截图出了它所有版本(请忽略小版本号)对应的支持的外部化配置情况:
说明:以下所有截图都来自Spring Boot官方文档的外部化配置Externalized Configuration部分,优先级从高到低。
1.0.0.RELEASE(7个):
1.1.0.RELEASE(9个):@PropertySource优先级有调整,增加了JNDI和random属性源支持
1.2.0.RELEASE(9个):
1.3.0.RELEASE(12个):增加了JSON格式配置、支持-{profile}.xxx
格式的配置
1.4.0.RELEASE(15个):增加了@TestPropertySource支持、ServletConfig和ServletContext属性源的支持
1.5.0.RELEASE(17个):增加了对调试工具@Devtools配置的支持、@SpringBootTest#properties的支持
2.0.0.RELEASE(17个):
2.1.0.RELEASE(17个):