原文地址: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-placeholderlocation="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-placeholderlocation="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!

转载于:https://www.cnblogs.com/davidwang456/p/5751706.html

6-tips-for-managing-property-files-with-spring--转相关推荐

  1. 【SSM - Spring篇01】spring详细概述,Spring体系结构,bean、property属性,Spring生命周期方法

    文章目录 1. Spring介绍 2. Spring体系架构 2.1 Spring核心容器(Core Container) 2.2 数据访问/集成(Data Access/Integration) 2 ...

  2. 读django文档——Managing static files (e.g. images, JavaScript, CSS)

    在上一篇读django文档--nginx + uwsgi 部署django项目_苦行僧的妖孽日常-CSDN博客  部署django项目后,发现在runserver时都能正常部署的 static 文件都 ...

  3. 【SpringBoot】 启动时,修改默认配置文件名称

    前言 spring boot version : 2.0.0.RELEASE maven version : 3.5.0 在不同的环境下,依赖的外部资源是不一样的.比如,在windows上开发,在li ...

  4. 春天的旁边_春天@PropertySource

    春天的旁边 Spring @PropertySource annotation is used to provide properties file to Spring Environment. Th ...

  5. 使用Spring的@Autowired 实现DAO, Service, Controller三层的注入(转)

    简述: 结合Spring和Hibernate进行开发 使用@Autowired实现依赖注入, 实现一个学生注册的功能,做一个技术原型 从DAO(Repository) -> Service -& ...

  6. 构建一个运行在Azure虚拟机上的MySQL Spring Boot应用程序

    \ 关键要点 \\ 从GitHub中获取一个简单的Spring Boot Java应用程序.\\t 将应用程序连接到Azure MySQL数据库服务.\\t 在Azure上配置一个运行WildFly的 ...

  7. Spring:源码解读Spring IOC原理

    2019独角兽企业重金招聘Python工程师标准>>> 一.什么是Ioc/DI? IOC容器:主要是完成了 完成对象的创建和依赖的管理注入等. 先从我们自己设计这样一个视角来考虑: ...

  8. 最渣的 Spring Boot 文章

    spring-boot-starter-parent Maven的用户可以通过继承spring-boot-starter-parent项目来获得一些合理的默认配置.这个parent提供了以下特性: 默 ...

  9. spring boot application.properties 属性详解

    2019年3月21日17:09:59 英文原版: https://docs.spring.io/spring-boot/docs/current/reference/html/common-appli ...

最新文章

  1. mysql数据库 中文乱码_在CMD中操作mysql数据库出现中文乱码解决方案
  2. 余额宝 vs. P2P网贷,谁更有生命力?
  3. KDD 2019 | 使用神经网络为A*搜索算法赋能:以个性化路径推荐为例
  4. LNMP架构介绍、MySQL安装、PHP安装、Nginx介绍
  5. Tokyo Tyrant安装和配置
  6. Python操作Excel文件汇总数据案例一则
  7. php简介及其发展,PHP 简介
  8. 第十一篇:Mysql系列
  9. C/c++输入输出函数
  10. [CF617E]XOR and Favorite Number/[CQOI2018]异或序列
  11. 关于vs中Microsoft.Office.Interop.MSProject
  12. Network: unavailable
  13. PyTorch搭建LSTM实现多变量多步长时间序列预测(二):单步滚动预测
  14. 加息+四巫日铁矿石大跌,棕榈油认沽最高30倍,豆一09-01继续反套2022.6.15
  15. GPT专业应用:如何让GPT策划方案
  16. STM32——三原色
  17. live555 日志
  18. 二十四节气-白露 | 白露至,秋实美
  19. TCP/IP技术回顾(3)—网际层
  20. 计划赶不上变化,为什么还要计划呢?

热门文章

  1. c语言大整数除法思路,大整数除法
  2. 全注解怎么使用分页插件_分页插件使用的方式
  3. c语言编程将图片上下翻转,C语言实现矩阵翻转(上下翻转、左右翻转)
  4. go int 最大值_Dig101 - Go之灵活的slice
  5. 任务间共享资源问题总结
  6. 类型两个数相减_小学数学简便计算12种分类+5种易错类型,打印出来给孩子练习!(可打印!)...
  7. 为什么 在内存中为什么 0xffff 是 -1
  8. 算术编码例题详解_百分数与百分点区别详解
  9. 集成学习(一)—预备知识:分类树和回归树
  10. pytorch 笔记:torch.distributions 概率分布相关(更新中)