6-tips-for-managing-property-files-with-spring--转
原文地址:http://www.summa.com/blog/2009/04/20/6-tips-for-managing-property-files-with-spring
What could be simpler than property files? In an enterprise application, it turns out, many things! In this post I’ll take a look at a few subtle complexities to managing properties in an enterprise Java Spring application, and hopefully demonstrate how a little fore-thought in design can yield big savings in terms of time, confusion, bugs, and gray hair down the road.
Types of Properties
Before designing an approach to managing property files, it's critical first to understand the types of properties are to be managed. Here are four characteristics to consider:
- Are some properties environment specific – in other words, do they have a different value in one environment than another? For example, a database connection string would differ in the TEST environment than it would the PROD environment.
- Do any properties contain sensitive information, like passwords or credentials, that can’t sit in plain text in the deployment unit (e.g. WAR, EAR)?
- Do any properties need to be located external from the deployment unit (e.g. on the file system rather than in the WAR, perhaps to be managed by a systems administrator)?
- Should properties be dynamic, in the sense that they can be updated at runtime (i.e. without requiring a restart of the application)?
Each of these special characteristics adds a degree of complexity to applications - necessitating additional infrastructure beyond the simple Java Properties class.
Spring’s PropertyPlaceholderConfigurer
Fortunately for us, the Spring framework, with the PropertyPlaceholderConfigurer and PropertyOverrideConfigurer, provides the features and hooks we need to manage these cases (with the exception “dynamic” properties). And true to its philosophy, Spring makes simple things simple, and complicated things possible.
The PropertyPlaceholderConfigurer allows properties to be pulled in to the application context file. For example, in the simplest case, a property “db.user” defined in database.properties could be pulled into the ${db.user} placeholder:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${db.user}"/>
<property name="password" value="${db.password}"/>
...
</bean>
The PropertyOverrideConfigurer works in the opposite way, pushing properties from property files into properties in the context file (without having to specifically define a place holder – e.g. ${db.user}). These are both well documented in the Spring API and documentation.
Tips
Given the different possible types of properties, and Spring's property framework, here are a few tips for managing them:
1) Consider using a JVM System property that sets the environment of the machine (e.g. "my.env=TEST"), telling the configurer which property file to use. For example:
<context:property-placeholder
location="classpath:db-${my.env}.properties"/>
If the "my.env" property was set to "TEST", then obviously the PropertyPlacementConfigurer would look for a file called "db-TEST.properties". For Tomcat, this property can be set in the admin console or defined in a startup script (e.g. "-Dmy.env=TEST") - neither of which is very elegant. Alternatively, it is possible to use JNDI with Tomcat, defining "my.env" in the server.xml and the context.xml of the web app. (Note, there are of course many other ways to solve this environment-specific problem, but this is an easy and relatively straight-forward one.)
2) It may be necessary to set the ignoreUnresolvablePlaceholders to true for any PropertyPlaceholderConfigurer, which will ensure that a configurer won’t fail if it can’t find a property. Why would this be a good thing? Oftentimes, one context file will import other context files, and each may have their own configurer. If ignoreUnresolvablePlaceholders is set to false (the default), then one configure would fail if it couldn’t find the property, even if another configurer down-stream could find it (see good explanation here). Beware, however, since this will suppress warnings for legitimate missing properties, making for some tough-to-debug configuration problems.
3) To encrypt properties, subclass the PropertyPlacementConfigurer and override the convertPropertyValue() method. For example:
protected String convertPropertyValue(String strVal) {
//if strVal starts with “!!” then return EncryptUtil.decrypt(strVal)
// else return strVal
}
4) Consider using the systemPropertiesMode property of the configurer to override properties defined in property files with System properties. For one-off environment specific properties this can be a helpful solution, however, for defining many properties, this configuration can be cumbersone.
5) For properties that need to be managed outside of the WAR, consider using a System property to define where the file is located. For example, the property ${ext.prop.dir} could define some default directory on the file system where external property files are kept:
<context:property-placeholder
location="file:///${ext.prop.dir}db.properties"/>
This entails, however, that this property is set for any process that leverages the Spring container (e.g. add the param to the Run Configurationfor integration/unit tests, etc.), otherwise the file would not be found. This can be a pain. To circumvent, the configurer can be overridden – changing the behavior such that it looks to the external directory only if the System property is set, otherwise it pulls from the classpath.
6) Beware of redundancy of environment-specific properties. For example, if the solution is to have one property file for each environment (e.g. “db-test.properties”, “db-dev.properties”, etc.), then maintaining these properties can be a bit of a nightmare - if a property "foo" is added, then it would have to be added to the property file for each environment (e.g. DEV, TEST, PROD, etc.). The PropertyOverrideConfigurer is appropriate to eliminate this redundancy, setting the default value in the application context itself, but then the overriding value in a separate file. It's important, however, to document this well, since it can look a bit "magical" to an unsuspecting maintenance developer who sees one value specified in the context file, but another used at runtime.
Conclusion
Managing properties for an enterprise application is a little trickier than one might expect. With Spring's property configurers, however, the toughest part is just knowing what you need - the rest comes out of the box, or with some minor extensions.
Hopefully a few of these tips will be useful for you. Please let me know some of your own!
6-tips-for-managing-property-files-with-spring--转的更多相关文章
- Spring property文件配置方法以及如何与工程分离
1,Spring使用property文件作为配置源 工程中难免出现一些需要每次部署都需要配置的参数,如数据源连接参数等,测试环境跟实际运行环境是不一样的. 使用spring框架的话,这些参 ...
- spring boot中的底层配置文件application.yam(application.property)的装配原理初探
*在spring boot中有一个基础的配置文件application.yam(application.property)用于对spring boot的默认设置做一些改动. *在spring boot ...
- 译:Spring框架参考文档之IoC容器(未完成)
6. IoC容器 6.1 Spring IoC容器和bean介绍 这一章节介绍了Spring框架的控制反转(IoC)实现的原理.IoC也被称作依赖注入(DI).It is a process wher ...
- Spring Boot Reference Guide
Spring Boot Reference Guide Authors Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, ...
- spring官网在线学习文档翻译
Core Technologies (核心技术) Version 5.0.8.RELEASE 版本5.0.8RELEASE This part of the reference documentati ...
- spring源码分析之<context:property-placeholder/>和<property-override/>
在一个spring xml配置文件中,NamespaceHandler是DefaultBeanDefinitionDocumentReader用来处理自定义命名空间的基础接口.其层次结构如下: < ...
- Spring:源码解读Spring IOC原理
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- Spring Boot文档阅读
原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...
- 玩转spring boot——properties配置
前言 在以往的java开发中,程序员最怕大量的配置,是因为配置一多就不好统一管理,经常出现找不到配置的情况.而项目中,从开发测试环境到生产环境,往往需要切换不同的配置,如测试数据库连接换成生产数据库连 ...
随机推荐
- iOS判断是模拟器还是真机
#if TARGET_IPHONE_SIMULATOR //模拟器 #elif TARGET_OS_IPHONE //真机 #endif
- ie浏览器下,get请求缓存问题
1 使用get请求数据 1)Java代码 $.getJSON("sortShow!sortShow?time="+new Date().getTime(),function(){} ...
- qunit 前端脚本测试用例
首先引用qunit 测试框架文件 <link rel="stylesheet" href="qunit-1.22.0.css"> <scrip ...
- Txt格式配置表无法解析的问题——BOM
今天再次遇到同一个问题:策划给来一个Txt格式配置表,我用解析类去读取,返回的结果为空.解析类参数是:主键key,文件名fileName,错误提示errorTip. 写读取语句的时候,主键key我是直 ...
- 求N个数的最大公约数和最小公倍数(转)
除了分解质因数,还有另一种适用于求几个较小数的最大公约数.最小公倍数的方法 下面是数学证明及算法实现 令[a1,a2,..,an] 表示a1,a2,..,an的最小公倍数,(a1,a2,..,an)表 ...
- Python之路Day20-Django一对一(多)以及Ajax
上节内容回顾 问题一:Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串-> URL对应关系(匹配) -> 视图函数 -> ...
- siteserver cms选择栏目搜索无效
标签必须以空格分开,且option 的value必须给id不能给名称
- Mysql的用户名密码设置方法
方法如下: 1, 关闭mysql服务 /etc/init.d/mysqld stop 2,使用 –skip-grant-tables选项启动mysql服务,可以修 改/etc/inin.d/mysql ...
- 使用html5 地理位置技术 和 百度地图api查询当前位置
使用了 zepto 和 requirejs define(['zepto'],function($){ var geolocation = { init:function(config,onSuc ...
- HDFS 架构解析
本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...