3、Spring EL 与第三方信息

3.1、Spring EL 与 集合

Spring EL基本表达式可以对集合中的信息进行读取操作,包括Collection、Map性质的集合。请看如下实例:

/**
 * 在这个bean被初始化时,进行集合数据的添加
 * @author yinwenjie
 */
@Component("myCollection")
public class CollectionPojo {
  private List<String> myList;
  private Map<String, Object> myMap;
  /**
   * 保证spring在构造这个bean实例时
   * 就向两个集合中写入了数据
   */
  public CollectionPojo() {
    this.myList = Arrays.asList(new String[]{"数据1","数据2","数据3","数据4"});
    this.myMap = new HashMap<>();
    myMap.put("key1", "value1");
    myMap.put("key2", "value2");
    myMap.put("key3", "value3");
  }
  ......
}

以上代码我们在myCollection这个bean被Spring容器初始化时,向bean中两种类型的集合属性写入了一些初始化值。接下来,我们通过@Value关键字,在依赖于这个bean的其它bean实例中,对属性进行赋值:

@Component("collectioSpel")
public class CollectionSpel {
  // 从列中取值
  @Value("#{myCollection.myList[0]}")
  private String value1;
  // 从键值对中取值
  @Value("#{myCollection.myMap['key1']}")
  private String value2;
  ......
}

这样一来,“value1”属性将得到“数据1”这个初始值,“value2”属性将得到“value1”这个初始化值。当然,在以上给出的“对myCollection bean进行初始化”的代码中,Spring XML还给出了一种配置方式,只是本专题中主要讲解是基于Spring boot的,所以就没有过多讲解Spring XML中的写法,这里给出补充的内容(通过XML进行myCollection bean中属性的初始化赋值):

......
<bean id="myCollection" class="...">
  <property name="addressList">
    <list>
      <ref bean="address1"/>
       <ref bean="address2"/>
       <value>Pakistan</value>
    </list>
  </property>
</bean>
......

3.2、Spring EL 与 配置(环境)信息

Spring EL 可以通过“$”关键字取得操作系统环境变量信息、应用程序运行时信息,以及应用程序配置文件中的信息。其中的原理是Spring中实现的某个配置信息获取配置器“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”和“org.springframework.context.support.PropertySourcesPlaceholderConfigurer”。前者为Spring 3.1之前的版本提供,而Spring 3.1之后的版本多采用后者(但是前者PropertyPlaceholderConfigurer并没有被放弃使用,详细情况读者可参见这两个类的官方注释)。

接下来我们来看看Spring EL通过“$”关键字如何取得操作系统环境变量信息、应用程序运行时信息,以及应用程序配置文件中的信息:

......
/**
 * 这个值来源于系统默认的配置文件中,
 * 文件名为application.yml或者application.properties
 */
@Value("${local.param1}")
private String value1;
/**
 * 从环境变量中取出PATH
 */
@Value("${PATH}")
private String path;
/**
 * 从环境变量中取出CLASSPATH
 */
@Value("${CLASSPATH}")
private String classpath;
/**
 * 取出应用程序的运行状态
 * 当前操作系统名字
 */
@Value("${os.name}")
private String osName;
/**
 * 取出应用程序的运行状态
 * 当前运行应用程序的用户的工作目录
 */
@Value("${user.dir}")
private String userDir;
/**
 * 取出应用程序的运行状态
 * 当前运行应用程序的用户的主目录
 */
@Value("${user.home}")
private String userHome;
/**
 * 取出应用程序的运行状态
 * 当前运行应用程序的用户的账户名
 */
@Value("${user.name}")
private String userName;
/**
 * 取出应用程序的运行状态
 * 当前jvm版本,注意不是jdk版本
 */
@Value("${java.vm.version}")
private String jvmVersion;
......

请注意,我们以上代码使用的示例环境为Spring Boot。后者为我们节省了大部分配置工作,例如我们可以直接将应用程序相关配置信息放置在规定的application.yml或者application.properties文件中,而无需在某个application.xml中指定配置文件。那么我们怎么知晓哪些操作系统环境变量信息、应用程序运行时信息可以通过“$”关键字进行加载呢?

  • 操作系统环境变量信息就是我们在Linux操作系统中(以CentOS操作系统为例),通过env命令能够获取到的那些环境变量信息。在java语言中我们可以通过以下代码将这些信息加载出来:
......
// Returns an unmodifiable string map view of the current system environment. 
// The environment is a system-dependent mapping from names to values which is passed from parent to child processes. 
// If the system does not support environment variables, an empty map is returned. 

Map<String, String> envs = System.getenv();
......

以下输出的调试信息,是笔者在自己的代码开发环境下得到的环境变量信息结果(由于篇幅原因,省去了部分):

......
PATH=D:\Program Files\Java\jdk1.8.0_144\jre\bin;D:/Program Files/Java/jdk1.8.0_144/bin/..,
USERDOMAIN_ROAMINGPROFILE=SC-201709191410, 
LOCALAPPDATA=C:\Users\Administrator\AppData\Local, 
PROCESSOR_LEVEL=6, 
SYSTEMDRIVE=C:, 
COMMONPROGRAMFILES(X86)=C:\Program Files (x86)\Common Files, 
USERDOMAIN=SC-201709191410, 
FPS_BROWSER_APP_PROFILE_STRING=Internet Explorer, 
LOGONSERVER=\\SC-201709191410, 
JAVA_HOME=D:\Program Files\Java\jdk1.8.0_144, 
PROMPT=$P$G, 
SESSIONNAME=Console, 
ALLUSERSPROFILE=C:\ProgramData, 
PROGRAMFILES(X86)=C:\Program Files (x86), 
......
USERPROFILE=C:\Users\Administrator, 
TMP=C:\Users\ADMINI~1\AppData\Local\Temp, 
PUBLIC=C:\Users\Public, 
NUMBER_OF_PROCESSORS=8
......
  • 而应用程序的运行时信息,是在应用程序运行过程中动态生成的信息。在java环境中,这些信息可以通过以下代码获得:
......
Properties properties = System.getProperties();
properties.list(System.out);
......

而在这个方法的官方注释中,也对这些应用程序运行时信息进行了部分说明(实际上根据操作系统的不同,信息还可能更多),参见以下的引用信息:

java.version: Java Runtime Environment version 
java.vendor: Java Runtime Environment vendor 
java.vendor.url: Java vendor URL 
java.home: Java installation directory 
java.vm.specification.version: Java Virtual Machine specification version 
java.vm.specification.vendor: Java Virtual Machine specification vendor 
java.vm.specification.name: Java Virtual Machine specification name 
java.vm.version: Java Virtual Machine implementation version 
java.vm.vendor: Java Virtual Machine implementation vendor 
java.vm.name: Java Virtual Machine implementation name 
java.specification.version: Java Runtime Environment specification version 
java.specification.vendor: Java Runtime Environment specification vendor 
java.specification.name: Java Runtime Environment specification name 
java.class.version: Java class format version number 
java.class.path: Java class path 
java.library.path: List of paths to search when loading libraries 
java.io.tmpdir: Default temp file path 
java.compiler: Name of JIT compiler to use 
java.ext.dirs: Path of extension directory or directories Deprecated. This property, and the mechanism which implements it, may be removed in a future release. 
os.name: Operating system name 
os.arch: Operating system architecture 
os.version: Operating system version 
file.separator: File separator (“/” on UNIX) 
path.separator: Path separator (“:” on UNIX) 
line.separator: Line separator (“\n” on UNIX) 
 // 这个属性已经演示过,代表启动当前应用程序的登录用户名 
user.name: User’s account name 
 // 这个属性也已经演示过,代表启动当前应用程序的用户,所使用的主目录 
user.home: User’s home directory 
 // 这个属性也已经演示过,代表启动当前应用程序的用户的工作目录 
user.dir: User’s current working directory ========================