[转自] http://unmi.cc/spring-injection-system-properties-env/

在 Spring 中为 javabean 注入属性文件中的属性值一般人都知道的,可以通过 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 引入一个属性文件,然后给 bean 指定属性的时候就可以用 ${jdbc.url} 方式赋值了。比如在 Spring 中是这样的配置:

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
</bean>

只是有时候我们需要给 bean 赋上系统属性(System.getProperties() ) 中的值或环境变量(System.getenv() ) 中的值,根据程序所处的环境产生不同的行为,这样我们无法事先在某个 properties 文件预先设定好值的。

这种需求也是不怕做不到就怕想不到,基于此,既然上面是用 PropertyPlaceholderConfigurer 来读取属性文件,那么有没有像 EnvironmentPlaceholderConfigurer 类似的东西呢,查下 api 没找到相关的,只是看下它有两个子类:

org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer

org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer

上面那两个类估计以后也是用得着,前面那个应该是从系统配置或注册表里要属性,后面的可以从 ServletContext 取相关属性值。

上面的思路应该是这样的,但实际上只要仔细阅读下 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 的 JavaDoc API 就会发现,它不光能从属性文件里取值,也能从系统属性,甚至是环境变量中取值。

Default property values can be defined via "properties", to make overriding definitions in properties files optional. A configurer will also check against system properties (e.g. "user.dir") if it cannot resolve a placeholder with any of the specified properties.
This can be customized via "systemPropertiesMode".

再往下看:

public void setSystemPropertiesMode(int systemPropertiesMode)

Set how to check system properties: as fallback, as override, or never. For example, will resolve ${user.dir} to the "user.dir" system property.

The default is "fallback": If not being able to resolve a placeholder with the specified properties, a system property will be tried. "override" will check for a system property first, before trying the specified properties. "never" will not check system properties
at all.

---------------------------------------------------------------------

public void setSearchSystemEnvironment(boolean searchSystemEnvironment)

Set whether to search for a matching system environment variable if no matching system property has been found. Only applied when "systemPropertyMode" is active (i.e. "fallback" or "override"), right after checking JVM system properties.

Default is "true". Switch this setting off to never resolve placeholders against system environment variables. Note that it is generally recommended to pass external values in as JVM system properties: This can easily be achieved in a startup script, even for
existing environment variables.

NOTE: Access to environment variables does not work on the Sun VM 1.4, where the corresponding System.getenv(java.lang.String) support was disabled - before it eventually got re-enabled for the Sun VM 1.5. Please upgrade to 1.5 (or higher) if you intend
to rely on the environment variable support.

说明了这个类可以从三个地方取属性值,并且可以设置覆盖关系,覆盖关系在此就不细究了。现在可以例子说明如何从系统属性或环境变量中取值了。演示一下从把系统属性 user.dir 和环境变量 COMPUTERNAME 注入到 javabean。

一. 要被注入系统属性和环境变量的 Bean

package cc.unmi.spring;

/**
* 通过 Spring 来向其中注入系统属性 workDir(${user.dir}, System.getProperty(""))
* 和环境变量 hostName(${COMPUTERNAME}, System.getenv().get("COMPUTERNAME"));
* @author Unmi
*
*/
public class Environments {
private String workDir;
private String hostName; public String getHostName() {
return hostName;
} public void setHostName(String hostName) {
this.hostName = hostName;
} public String getWorkDir() {
return workDir;
} public void setWorkDir(String workDir) {
this.workDir = workDir;
}
}

二. Spring 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <bean id="env" class="cc.unmi.spring.Environments">
<property name="workDir" value="${user.dir}"/>
<property name="hostName" value="${COMPUTERNAME}"/>
</bean>
</beans>

三. 测试客户端代码

package cc.unmi.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; import cc.unmi.spring.Environments; /**
* 测试客户端
* @author Unmi
*/
public class TestClient { public static void main(String[] args) {
BeanFactory context = new ClassPathXmlApplicationContext("applicationContext.xml");
Environments env = context.getBean(Environments.class);
System.out.println("Working directory: " + env.getWorkDir());
System.out.println("Host name: " + env.getHostName());
}
}

四. 执行上面的 TestClient 后控制台下输出的结果是:

Working directory: D:\workspaces\j2ee\TestSpring

Host name: Unmi-Computer

这显示了 Spring 已成功向 Environments 注入了系统属性 user.dir 和环境变量 COMPUTERNAME。

注:你可以用 System.getProperties().list(System.out) 打印出系统属性,还不知道系统中可用哪个命令查得到其中的值:显示出来是这样的:

-- listing properties --

java.runtime.name=Java(TM) SE Runtime Environment

sun.boot.library.path=C:\Program Files\Java\jre6\bin

java.vm.version=17.1-b03

java.vm.vendor=Sun Microsystems Inc.

java.vendor.url=http://java.sun.com/

path.separator=;

java.vm.name=Java HotSpot(TM) Client VM

file.encoding.pkg=sun.io

user.country=US

...................................

环境变量可以用 System.out.print(System.getenv()) 打印出来,对应着 Windows 中的 set 命令或 Linux  下的 env 输出的值,System.getenv() 是个 Map,所以打印出这样子的:

{USERPROFILE=C:\Documents and Settings\Unmi, JAVA_HOME=C:\Program Files\Java\jdk1.6.0_20, TEMP=C:\DOCUME~1\uqiu\LOCALS~1\Temp, OS=Windows_NT, COMPUTERNAME=Unmi-Computer, .......}

Spring中如何向 Bean注入系统属性或环境变量的更多相关文章

  1. java中获取系统属性以及环境变量

    java中获取系统属性以及环境变量 System.getEnv()和System.getProperties()的差别 从概念上讲,系统属性 和环境变量 都是名称与值之间的映射.两种机制都能用来将用户 ...

  2. Java获取系统属性及环境变量

    当程序中需要使用与操作系统相关的变量(例如:文件分隔符.换行符)时,Java提供了System类的静态方法getenv()和getProperty()用于返回系统相关的变量与属性,getenv方法返回 ...

  3. JVM系统属性 OS环境变量 JVM启动参数

    JVM系统属性(System Properties) 1.不支持通过文件查看和设置系统属性 2.可以通过JDK自带的工具jvisulavm.exe查看 3.可以在Java程序中使用API来查看系统属性 ...

  4. maven中可以直接引用的java系统属性和环境变量属性

    一.查看命令: 1 mvn help :system 二.引用 在pom文件中通过 ${变量名}来引用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

  5. Spring中常见的bean创建异常

    Spring中常见的bean创建异常 1. 概述     本次我们将讨论在spring中BeanFactory创建bean实例时经常遇到的异常 org.springframework.beans.fa ...

  6. 半夜思考之查漏补缺, 在 Spring中, 所有的 bean 都是 Spring 创建的吗 ?

    Spring 是一个 bean 容器, 负责 bean 的创建, 那么所有的 bean对象都是 Spring 容器创建的吗 ? 答案是否定的. 但是乍一想, 好像所有的对象都是 Spring 容器负责 ...

  7. 九、Spring中使用@Value和@PropertySource为属性赋值

    首先回顾下在xml中我们是如何为spring的bean进行属性赋值呢? 大体是这样的 <bean id="person" class="com.atguigu.be ...

  8. Windows 如何在cmd命令行中查看、修改、删除与添加环境变量

    转自:http://www.cnblogs.com/saptechnique/archive/2013/02/17/2914222.html 首先明确一点: 所有的在cmd命令行下对环境变量的修改只对 ...

  9. 如何在cmd命令行中查看、修改、删除与添加环境变量,语法格式例子:set path;echo %APPDATA%

    如何在cmd命令行中查看.修改.删除与添加环境变量 首先明确一点: 所有的在cmd命令行下对环境变量的修改只对当前窗口有效,不是永久性的修改.也就是说当关闭此cmd命令行窗口后,将不再起作用.永久性修 ...

随机推荐

  1. win32多线程 (一) 线程创建与结束等待

    #include "stdafx.h"#include <Windows.h>#include <iostream> using namespace std ...

  2. bootstrap三列布局

    <!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8&quo ...

  3. 三维GIS

    三维GIS数据结构 三维GIS数据库 三维渲染显示 点云处理 cnki:http://kns.cnki.net/kns/brief/default_result.aspx

  4. MVC 基本概念

    1. M(Model-模型): 数据模型. 负责定义信息格式与信息反问的界面,包括商业逻辑,数据反问.(可以理解成是三层模式中的 BLL+DAL ) 2. V(View-视图): 负责用户界面 UI ...

  5. Java java.lang.Thread#join()方法分析

    结论:A 线程调用 B 线程对象的 join 方法,则 A 线程会被阻塞,直到 B 线程 挂掉 (Java Doc 原话: Watis for this thread to die). 一.分析 查看 ...

  6. Canvas保存为图片

    public static void GenerateCanvas(string imgSaveName, int canvasWidth, int canvasHeight, string imgD ...

  7. DataGridView自定义行样式和行标题

    定义两个样式对象: //定义两种行样式 private DataGridViewCellStyle m_RowStyleNormal; private DataGridViewCellStyle m_ ...

  8. 【C#】特性标签中的属性解释

    第一个为特性作用于类,或者接口(interface) 第二个为是否允许重叠定义,就是连续写两个特性标签 第三个为是否继承,当继承时候,除输出子类外,父类也将输出

  9. 《C#多线程编程实战》2.9 ReaderWirterLockSlim

    可以多线程进行读写操作. 比如书上的示例代码是三个线程进行读取,两个线程进行写入工作. 如果 用之前学过的也不是不可以用,但是用的有些多. 所有ReaderWirterLockSlim专门为此而来. ...

  10. golang文件处理函数openfile与linux系统的文件函数的耦合

    golang运行最理想的环境是linux系统中,编译速度和执行速度都比较快,本文是关于golang中的文件操作函数 在golang标准库中os包提供了不依赖平台的借口,但是使用的风格是unix风格的. ...