[转自] 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. PHP学习笔记之continue与break

    百度中有人这样解释:break是结束整个循环体,continue是结束单个循环体.昨天看燕十八老师PHP视频,讲到break,continue时,举了一个例子,理解更容易.天龙八部中,西夏国公主选婿, ...

  2. Python开发 第一篇 python的前世今生

    Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...

  3. 设计模式11: Flyweight 享元模式(结构型模式)

    Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...

  4. 明码——第九届蓝桥杯C语言B组(省赛)第二题

    原创 标题:明码 汉字的字形存在于字库中,即便在今天,16点阵的字库也仍然使用广泛.16点阵的字库把每个汉字看成是16x16个像素信息.并把这些信息记录在字节中. 一个字节可以存储8位信息,用32个字 ...

  5. .net 3.5 Lambda表达式

    Lambda表达式 转自http://www.cnblogs.com/kingmoon/archive/2011/05/03/2035696.html "Lambda表达式"是一个 ...

  6. HTML5游戏开发进阶指南 中文pdf扫描版​

    HTML5游戏开发进阶指南介绍了HTML5游戏开发的一般过程和技巧.全书共分12章,第1章介绍了本书相关的HTML5的诸多新特性,包括在canvas上绘图.播放声音等,另外还引入了子画面页的概念:第2 ...

  7. 异常:已捕获: "Error creating context 'spring.root': 未将对象引用设置到对象的实例。" (System.Configuration.ConfigurationErrorsException) 捕获到一个 System.Configuration.ConfigurationErrorsException: "Error creating context 'sp

    查看所指定name的context是否注册成功,以后用此容器来获取其中的object. 常见的使用方式: Application_Start中使用ContextRegistry.GetContext( ...

  8. java中int转String 固定位数 不足补零

    转载自:http://ych0108.iteye.com/blog/2174134 String.format("%010d", 25); //25为int型 0代表前面要补的字符 ...

  9. Mybatis中的多表查询 多对多

    示例:用户和角色 一个用户可以有多个角色 一个角色可以赋予多个用户 步骤: 1.建立两张表:用户表,角色表 让用户表和角色表具有多对多的关系. 需要使用中间表,中间表中包含各自的主键,在中间表中是外键 ...

  10. Balance(Stack)

    栈的运用 mooc视频连接 #include <iostream> using namespace std; ]; ; void Push(char c) { ) { Top = ; S[ ...