`
dylan0514sina.cn
  • 浏览: 92083 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

支持不同运行环境下的属性处理--Environment 特性

 
阅读更多
介绍
Environment架构是spring 3.1版本引入的,它代表当前应用运行环境比如servlet,porlet
。主要处理两部分的内容 profiles和properties,properties将使用org.springframework.core.env.PropertyResolver解析。而Environment继承了此实现。

背景
   一个profile是有名字的,在激活状态下它代表注册在容器中的一组bean definitions.一组bean可以通过xml和注解配置被归于到一个profile中,只要这个profile被激活了那这组bean则是可以被注册的。那Environment则担任了访问profile的角色。
   Properties 几乎在所有的应用中都担任着重要角色。可能来源于properties file,JVM system properties, system environment variables, JNDI, servlet context parameters, ad-hoc Properties objects, Maps等等。那Environment则为用户提供了方便的接口以配置property Source和通过它们解析属性。

使用EnvironmentAware访问
  可以在ApplicationContext 中为定义一个实现EnvironmentAware接口或@inject来了解这个Environment
  在多数情况下,应用中的bean不需要与Enviroment直接交互,相反我们声明诸如PropertySourcesPlaceholderConfigurer的beanFactory处理器(本身实现了EnvironmentAware接口)和<context:property-placeholder/>来解析${}
  如果想修改ActiveProfile和Properties则使用ConfigurableEnvironment

理解property sources
   Environment架构提供了在一组有层次的property sources上进行迭代查询操作。便于理解,请看下面的例子
ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);

   以上片段中,我们请求spring容器在当前环境下是否存在'foo'属性。这样的请求会触发Environment 对象查询搜索一组PropertySource 对象,所谓PropertySource 代表简简单单的键值对。在默认DefaultEnvironment 下,spring配置了两种PropertySource ----一种代表JVM系统属性等价于System.getProperties()返回属性集;另一种代表系统环境变量等价于System.getenv()属性集。就是说如果一个'foo'JVM系统属性或一个'foo'环境变量出现在运行时,那env.containsProperty("foo")调用
将返回true.
   而且搜素是具有先后概念的,默认情况下系统属性优先于环境变量。如果'foo'同时出现在JVM系统属性和环境变量中,则系统属性'foo'将胜出。
   更重要的是搜素顺序是可以定制的,当想要自定义属性集插入到搜索序列中时可以实现PropertySource 接口并添加到Environment的一组PropertySources中。
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new MyPropertySource());

   以上片段中MyPropertySource 被添加到搜索序列中且具有最高优先级。如果它包含'foo',则立即返回不用继续搜索其他的PropertySource 。
MutablePropertySources API提供了更精细化的方法管理一组PropertySource,将在最后介绍

注意:在单独的Application应用中,默认使用DefaultEnvironment;
      在web应用中,则使用DefaultWebEnvironment,它在DefaultEnvironment基础上多了servletContext和servletConfig初始化参数
      在porlet应用中,则使用DefaultPortletEnvironment,它在DefaultEnvironment基础上 多了porletContext和porletConfig初始化参数;
         以上两种可以启用JndiPropertySource
使用property sources
   理解property sources基本概念和与Environment的关系之后,如何将这些运用到开发中来,考虑几个场景
场景1:${placeholder}在<import/> 中
假如有几个特定于某些用户的spring配置文件,那么我们可以有条件的载入这些文件通过'customer' 属性值
<beans>
    <import resource="com/bank/service/${customer}-config.xml"/>
</beans>

spring 3.1之前,import元素中占位符的值只能依赖于JVM system properties 和environment variables,现在就不是这样。Environment架构完全整合到容器中,通过它很容器解决属性占位符路由问题。就是说可以控制搜索过程,比如改变JVM system properties 和environment variables优先级、完全删除它们、添加自己的Property Source。

注意:<import/>元素的处理在BeanFactoryPostProcessors 调用之前,就是说PropertyPlaceholderConfigurer在这无效,因为environment对象和他的一组property source在refresh之前所以在<import/>中的占位符将被正确解析,没有任何生命周期问题。

场景2:${placeholder}在bean definition
多数开发人员熟悉使用PropertyPlaceholderConfigurer 或者 <context:property-placeholder/>替换bean配置中的 ${...},例如
context:property-placeholder location="com/bank/config/datasource.properties"/>
 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClass" value="${database.driver}"/>
    <property name="jdbcUrl" value="${database.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
</bean>

自spring 3.1以来<context:property-placeholder/>不再注册PropertyPlaceholderConfigurer,而是注册PropertySourcesPlaceholderConfigurer,这个组件仍然会查看datasource.properties以解析${database.*},如果没找到则在当前Environment 中查找。当然我们可以改变这种顺序。

注意:在某些情况下,<context:property-placeholder/>依旧会注册PropertyPlaceholderConfigurer,在spring-context schema 3.1版本中,system-properties-mode属性已经移除掉。这是因为这个属性在PropertySources-/Environment世界里不再起作用,但如果使用spring3.1开发,而schema则使用spring-context-3.0.xsd并且设置了system-properties-mode,那<context:property-placeholder>会注册PropertyPlaceholderConfigurer。
<context:property-placeholder system-properties-mode=""/>


在web应用中操纵 property sources
  目前为止我们都是通过编程式的访问ApplicationContext操纵property sources
事实上很多spring应用时基于web的,使用ContextLoaderListener管理ApplicationContext。因此引入ApplicationContextInitializer 和它的伙伴servlet context 参数contextInitializerClasses(指定多个,以逗号分隔)
<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.bank.MyInitializer</param-value>
</context-param>

public class MyInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {
    public void initialize(ConfigurableWebApplicationContext ctx) {
        PropertySource ps = new MyPropertySource();
        ctx.getEnvironment().getPropertySources().addFirst(ps);
        // perform any other initialization of the context ...
    }

实现和注册ApplicationContextInitializer时提供了一种方便的方式在容器refresh之前和ApplicationContext交互。正好在这操纵property sources,也可以设置bean.xml setConfigLocations
1
1
分享到:
评论

相关推荐

    powerbuilder

    不同类型的打印机使用不同的控制序列,你需要翻一翻你的打印机手册。由于PowerBuilder使用数值0(即ASCII码为0的字符)结束每个字符串,因此,如果打印控制序列中包含了数值0,应用程序需要使用其它字符在参数string...

    新版Android开发教程.rar

    � 采用了对有限内存、电池和 CPU 优化过的虚拟机 Dalvik , Android 的运行速度比想象的要快很多。 � 运营商(中国移动等)的大力支持,产业链条的热捧。 � 良好的盈利模式( 3/7 开),产业链条的各方:运营商、...

    UNIX环境高级编程_第2版.part2

    UNIX环境高级编程_第2版 ----------------------------------------------------------- 共两个压缩包( UNIX环境高级编程_第2版.part1 UNIX环境高级编程_第2版.part1 ) ------------------------------------------...

    UNIX环境高级编程_第2版.part1

    UNIX环境高级编程_第2版 ----------------------------------------------------------- 共两个压缩包( UNIX环境高级编程_第2版.part1 UNIX环境高级编程_第2版.part1 ) ------------------------------------------...

    Visual Basic 6编程技术大全 中译本扫描版带书签 2/2

    3.1.1 运行时属性59 3.1.2捕获键盘活动60 3.1.3数字的校验例程61 3.1.4 CausesValidation属性和Validate事件63 3.1.5自动跳格字段65 3.1.6格式化文本65 3.1.7多行TextBox控件69 3.2 Label和Frame控件70 3.2.1 Label...

    Visual Basic 6编程技术大全 中译本扫描版带书签 1/2

    3.1.1 运行时属性59 3.1.2捕获键盘活动60 3.1.3数字的校验例程61 3.1.4 CausesValidation属性和Validate事件63 3.1.5自动跳格字段65 3.1.6格式化文本65 3.1.7多行TextBox控件69 3.2 Label和Frame控件70 3.2.1 Label...

    springboot参考指南

    在Spring环境中使用YAML暴露属性 iii. 23.6.3. Multi-profile YAML文档 iv. 23.6.4. YAML缺点 vii. 23.7. 类型安全的配置属性 i. 23.7.1. 第三方配置 ii. 23.7.2. 松散的绑定(Relaxed binding) iii. 23.7.3. @...

    Ant权威指南

    最后,本书还是一本详尽的 Ant 字典,列出了 Ant 各种内建任务具体支持的属性,未见任何错误;当然了,都是 1.5 之前的特性了,不过和 1.8.2 有 90% 左右一致。 序 前言 第一章 Ant入门 文件和目录 Ant的构建文件 ...

    iuhyiuhkjh908u0980

    前面已经把ant的基本运行环境搭建好了,在接下来的工作中,将一步一步的开始构建我们的项目。选择项目目录结构:一个项目开始的时候,选择一个合适的项目目录结构,是一件很重要的事情,可能你会很习惯由IDE自动创建...

    linux.chm文档

    chown -R user1 directory1 改变一个目录的所有人属性并同时改变改目录下所有文件的属性 chgrp group1 file1 改变文件的群组 chown user1:group1 file1 改变一个文件的所有人和群组属性 find / -perm -u+s 罗列一...

    C#微软培训资料

    2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 工 具 .17 2.4 小 结 .19 第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs ...

    Maven权威指南 很精典的学习教程,比ANT更好用

    2. 安装和运行Maven 2.1. 验证你的Java安装 2.2. 下载Maven 2.3. 安装Maven 2.3.1. 在Mac OSX上安装Maven 2.3.2. 在Microsoft Windows上安装Maven 2.3.3. 在Linux上安装Maven 2.3.4. 在FreeBSD或OpenBSD上...

    UNIX环境高级编程

    本书是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的第2版。在 本书第1版出版后的十几年中,UNIX行业已经有了巨大的变化,特别是影响UNIX编程接口的有关标准变 化很大。本书在保持了...

    API之网络函数---整理网络函数及功能

    LZOpenFile 该函数能执行大量不同的文件处理,而且兼容于压缩文件 LZRead 将数据从文件读入内存缓冲区 LZSeek 设置一个文件中进行读写的当前位置 MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间 ...

    JAVA基础课程讲义

    Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的编写和运行过程 19 第一个程序常见错误 20 第一个JAVA程序的总结和提升 20 常用...

    亮剑.NET深入体验与实战精要2

    1.2 .NET的几个特性 7 1.3 万丈高楼平地起:面试者必会 9 1.3.1 C#介绍 10 1.3.2 命名空间 10 1.3.3 C#语法格式要点 10 1.3.4 变量 12 1.3.5 类型推断 12 1.3.6 变量的作用域 13 1.3.7 常量 16 1.3.8 流程控制 16 ...

    亮剑.NET深入体验与实战精要3

    1.2 .NET的几个特性 7 1.3 万丈高楼平地起:面试者必会 9 1.3.1 C#介绍 10 1.3.2 命名空间 10 1.3.3 C#语法格式要点 10 1.3.4 变量 12 1.3.5 类型推断 12 1.3.6 变量的作用域 13 1.3.7 常量 16 1.3.8 流程控制 16 ...

    C#浏览器编程,学习使用

    若缓存中保存了该项,浏览器就直接从缓存中得到该项副本而不必从网络获取,这样就明显地改善浏览器的运行特性。 10) 但缓存要占用磁盘大量的空间,而浏览器性能的改善只有在用户再次查看缓存中的页面时才有帮助。 11...

Global site tag (gtag.js) - Google Analytics