http://www.kafeitu.me/solution/2013/06/29/a-successful-cofiguration-file-management-solution.html
==============================================================================================
一个基于Maven的配置文件管理成功案例
引言
配置文件几乎是每个项目中不可或缺的文件类型之一,常用的配置文件类型有xml、properties等,配置文件的好处不言而喻,利用配置文件可以灵活地设置软件的运行参数,并且可以在更改配置文件后在不重启应用的情况下即时生效。
写这篇文章的原因是最近在一个项目中引入了我对配置文件的管理方式,我觉得有必要与大家分享,希望能抛砖引玉。
1. 我所知道的配置文件管理方式
下面大概列出了几类对配置文件的管理方式,请对号入座^_^
1.1 配置文件是什么?
除非应用不需要配置文件(例如Hello World),否则请无视,continue;
1.2 数据库方式
把配置文件保存在数据库,看起来这种方式很不错,配置不会丢失方便管理,其实问题很大;举个简单的例子,在A模块需要调用B模块的服务,访问B模块的URL配置在数据库,首先需要在A中读取B模块的URL,然后再发送请求,问题紧随而来,如果这个功能只有一个开发人员负责还好,假如多个人都要调试那就麻烦了,因为配置保存在数据库(整个Team使用同一个数据库测试),每个开发人员的B模块的访问端口(Web容器的端口)又不相同或者应用的ContextPath不同,要想顺利调试就要更改数据库的B模块URL值,这样多个开发人员就发生了冲突;问题很严重!
1.3 XML方式
对于使用SSH或者其他的框架、插件的应用在src/main/resources下面肯定有不少的xml配置文件,今天的主题是应用级的配置管理,所以暂且抛开框架必须的XML配置文件,先来看看下面的XML配置文件内容。
1
2
3
4
5
|
<!--?xml version="1.0" encoding="UTF-8"?-->
<
systemconfig
>
<
param
code
=
"SysName"
name
=
"系统名称"
type
=
"String"
value
=
"XXX后台系统"
>
<
param
code
=
"SysVersion"
name
=
"系统版本"
type
=
"String"
value
=
"1.0"
>
</
systemconfig
>
|
这种方式在之前很受欢迎,也是系统属性的主要配置方式,不过使用起来总归不太简洁、灵活(不要和我争论XML与Properties)。
1.4 属性文件方式
下面是kft-activiti-demo中application.properties文件的一部分:
1
2
3
4
5
6
7
8
9
10
11
12
|
sql.
type
=h2
jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:
file
:~
/kft-activiti-demo
;AUTO_SERVER=TRUE
jdbc.username=sa
jdbc.password=
system.version=${project.version}
activiti.version=${activiti.version}
export
.diagram.path=${
export
.diagram.path}
diagram.http.url=${diagram.http.url}
|
相比而言属性文件方式比XML方式要简洁一些,不用严格的XML标签包装即可设置属性的名称,对于多级配置可以用点号(.)分割的方式。
2. 分析我的管理方式
我在几个项目中所采用的是第4中方式,也就是属性文件的方式来管理应用的配置,读取属性文件可以利用Java的Properties对象,或者借助Spring的properties模块。
2.1 利用Maven资源过滤设置属性值
简单来说就是利用Maven的Resource Filter功能,pom.xml中的build配置如下:
1
2
3
4
5
6
7
8
|
<
build
>
<
resources
>
<
resource
>
<
directory
>src/main/resources</
directory
>
<
filtering
>true</
filtering
>
</
resource
>
</
resources
>
</
build
>
|
这样在编译时src/main/resources目录下面中文件()只要有${foo}占位符就可以自动替换成实际的值了,例如1.4节中属性system.version使用的是一个占位符而非实际的值,${project.version}表示pom.xml文件中的project标签的version。
属性export.diagram.path、diagram.http.url也是使用了占位符的方式,很明显这两个属性的值不是pom.xml文件可以提供,所以如果要动态设置值可以通过在pom.xml中添加的方式,或者把放在profile中,如此可以根据不同的环境(开发、UAT、生产)动态设置不同的值。
当然也可以在编译时通过给JVM传递参数的方式,例如:
mvm clean compile -Dexport.diagram.path=/var/kft/diagrams
编译完成后查看target/classes/application.properties文件的内容,属性export.diagram.path的值被正确替换了:
export.diagram.path=/var/kft/diagrams
2.2 读取配置文件
读取配置文件可以直接里面Java的Properties读取,下面的代码简单实现了读取属性集合:
1
2
3
4
5
|
Properties props =
new
Properties();
ResourceLoader resourceLoader =
new
DefaultResourceLoader();
Resource resource = resourceLoader.getResource(location);
InputStream is = resource.getInputStream();
propertiesPersister.load(props,
new
InputStreamReader(is,
"UTF-8"
));
|
如果在把读取的属性集合保存在一个静态Map对象中就可以在任何可以执行Java代码的地方获取应用的属性了,工具类PropertiesFileUtil简单实现了属性缓存功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
class
PropertyFileUtil {
private
static
Properties properties;
public
void
loadProperties(String location) {
ResourceLoader resourceLoader =
new
DefaultResourceLoader();
Resource resource = resourceLoader.getResource(location);
InputStream is = resource.getInputStream();
PropertiesPersister propertiesPersister =
new
DefaultPropertiesPersister();
propertiesPersister.load(properties,
new
InputStreamReader(is,
"UTF-8"
));
}
// 获取属性值
public
static
String get(String key) {
|