概述

Environment 这个接口代表应用运行时的环境。它代表了两方面、一个是 profile 一个是 properties。访问 property 的方法通过 Environment 继承的接口 PropertyResolver 暴露出去。

根据 profile 是否被激活、控制着哪些 bean 的信息会被注册到 Spring 的容器中。Environment 的作用就是提供获取当前哪些 profile 被激活、哪些 profile 是默认被激活的方法。

image-20210313103649279

properties 的来源有以下的几个方面

  • properties 文件
  • JVM 系统属性
  • 系统环境变量
  • JNDI
  • Servlet 上下文变量

environment 为用户提供了简易的接口让用户去配置属性源(property source) 并且从属性源中解释属性出来。

PropertyResolver

除了常规的方法、有两个挺有一些的方法、用于解释 SPEL 表达式、当然只是 ${}的、如果想要解释 #{} 的、可以使用 StringValueResolver 解释。

PropertySource

PropertySource 非常类似于 Map,数据源可来自 Map、Properties、Resource 等。PropertySource 接口有两个特殊的子类:StubPropertySource 用于占位用,ComparisonPropertySource 用于集合排序,不允许获取属性值。

@Test
public void PropertySourceTest() throws IOException {
    PropertySource mapPropertySource = new MapPropertySource("map",
            Collections.singletonMap("key", "source1"));
    Assert.assertEquals("value1", mapPropertySource.getProperty("key"));

    ResourcePropertySource resourcePropertySource = new ResourcePropertySource(
            "resource", "classpath:resources.properties");
    Assert.assertEquals("value2", resourcePropertySource.getProperty("key"));
}

CompositePropertySource

CompositePropertySource 提供了组合 PropertySource 的功能,查找顺序就是注册顺序。

@Test
public void CompositePropertySourceTest() throws IOException {

    PropertySource propertySource1 = new MapPropertySource("source1",
            Collections.singletonMap("key", "value1"));
    PropertySource propertySource2 = new MapPropertySource("source2",
            Collections.singletonMap("key", "value2"));

    CompositePropertySource compositePropertySource = new CompositePropertySource("composite");
    compositePropertySource.addPropertySource(propertySource1);
    compositePropertySource.addPropertySource(propertySource2);
    Assert.assertEquals("value1", compositePropertySource.getProperty("key"));
}

PropertySources

另外还有一个 PropertySources,从名字可以看出其包含多个 PropertySource。默认提供了一个 MutablePropertySources 实现,可以调用 addFirst 添加到列表的开头,addLast 添加到末尾,另外可以通过 addBefore(propertySourceName, propertySource) 或 addAfter(propertySourceName, propertySource) 添加到某个 propertySource 前面/后面;最后大家可以通过 iterator 迭代它,然后按照顺序获取属性。

注意:PropertySource 的顺序非常重要,因为 Spring 只要读到属性值就返回。

@Test
public void PropertySourcesTest() throws IOException {
    PropertySource propertySource1 = new MapPropertySource("source1",
            Collections.singletonMap("key", "value1"));
    PropertySource propertySource2 = new MapPropertySource("source2",
            Collections.singletonMap("key", "value2"));

    MutablePropertySources propertySources = new MutablePropertySources();
    propertySources.addFirst(propertySource1);
    propertySources.addLast(propertySource2);

    Assert.assertEquals("value1", propertySources.get("source1").getProperty("key"));
    Assert.assertEquals("value2", propertySources.get("source2").getProperty("key"));
}

Environment

其主要实现类是 AbstractEnvironment 中

StandardEnvironment 覆盖父类设置属性源的方法、向其增加系统属性和系统环境变量的属性源。

image-20210313160919184

而StandardServletEnvironment 则是增加了 servlet相关的两个属性源、并且实现了初始化属性源的方法。将

StubPropertySource 替换为 servlet 相关的属性源。

大体上就是这样吧、一直不太理解 Environment 到底是何物、大概知道了现在。

https://www.cnblogs.com/binarylei/p/10280374.html

posted on 2021-03-13 22:16  -CoderLi  阅读(672)  评论(0编辑  收藏  举报