1. 程式人生 > 其它 >Spring原始碼分析之Environment

Spring原始碼分析之Environment

前言

Environment表示當前Spring程式執行的環境,主要管理profiles和properties兩種資訊。
profiles用來區分當前是dev(開發)環境還是test(測試)環境或者prod(生產)環境。
properties表示所有的屬性,包括作業系統環境變數,如PATH,JDK相關配置,如java.vm.specification.version(JDK版本),還有我們通過properties檔案和yml檔案自定義的屬性。

Environment

相關類圖如下

預設實現為StandardEnvironment,內部委託PropertySourcesPropertyResolver(屬性解析器)來處理屬性相關的新增和查詢。

Profile

import org.springframework.core.env.StandardEnvironment;

public class TestProfile {

  public static void main(String[] args) {
    StandardEnvironment environment = new StandardEnvironment();
    environment.addActiveProfile("dev");
    for (String defaultProfile : environment.getDefaultProfiles()) {
      System.out.println(defaultProfile);//default
    }
    for (String activeProfile : environment.getActiveProfiles()) {
      System.out.println(activeProfile);//dev
    }
  }

}

管理activeProfile(活躍的profile)。

系統屬性

import org.springframework.core.env.StandardEnvironment;

public class TestSystemProperties {

  public static void main(String[] args) {
    StandardEnvironment environment = new StandardEnvironment();
    environment.getSystemProperties().forEach((k, v) -> {
      System.out.println(k + ":" + v);
    });
    System.out.println("====================");
    environment.getSystemEnvironment().forEach((k, v) -> {
      System.out.println(k + ":" + v);
    });
    String property = environment.getProperty("os.version");
    System.out.println(property);
  }

}

載入及查詢系統屬性,內部是通過System.getProperties()來實現的。

自定義屬性

定義一個properties檔案

name=lisi
age=23
import java.io.IOException;
import java.util.Properties;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

public class TestLocalProperties {

  public static void main(String[] args) throws IOException {
    StandardEnvironment environment = new StandardEnvironment();
    System.out.println(environment.getProperty("name"));//null
    Properties properties = PropertiesLoaderUtils
        .loadProperties(new ClassPathResource("abc.properties"));
    PropertiesPropertySource propertySource = new PropertiesPropertySource("local", properties);
    environment.getPropertySources().addLast(propertySource);
    System.out.println(environment.getProperty("name"));//lisi
  }

}

從classpath下載入此properties檔案,新增到environment中,每一個properties檔案都可以看做一個PropertySource,environment中包含一系列的PropertySource。

佔位符

name=lisi
nameAndAge=${name}${age:23}
import java.io.IOException;
import java.util.Properties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.PropertyPlaceholderHelper;

public class TestPlaceholderHelper {

  public static void main(String[] args) throws IOException {
    Properties properties = PropertiesLoaderUtils
        .loadProperties(new ClassPathResource("abc.properties"));
    PropertyPlaceholderHelper placeholderHelper = new PropertyPlaceholderHelper("${", "}", ":",
        true);
    String result = placeholderHelper.replacePlaceholders("${nameAndAge}", properties);
    System.out.println(result);//lisi23
  }

}

使用PropertyPlaceholderHelper用來處理佔位符,${name}${age:23}表示取屬性name的值和屬性age的值,:表示如果age屬性值不存在,取預設值23。
PropertySourcesPropertyResolver(屬性解析器)內部就是使用PropertyPlaceholderHelper來處理佔位符的。

在Spring中的使用

在Spring中所有關於屬性的管理,都是通過environment來完成的,在處理@Value註解的注入時,就是通過解析佔位符來實現的。