简约之美jodd--props属性使用
Prop是一个超级properties;包含了很多jdk缺失的东西:utf-8支持,宏,分区,profiles,全配置等等。
属性存储在一个或者多个*.props文件,而且它是开放的,支持多种类型的资源。更重要的是,它和java properties是兼容的。
Props的目标不是提供一个最大限度地配置解决方案,而是提供一个比java properties更好的选择。因此如果在应用中使用到properties,考虑使用Props来替代。
基本规则
下面是介绍props文件格式的一组基本规则。其中的一些规则如下示例:
utf8编码
默认情况下,props文件是utf8编码,也可以使用别的任意编码格式。不管使用哪种编码格式,props加载java properites时仍然使用ISO 8859-1.
去除空白字符
分区名称和属性名称的开头结尾的空白字符将被去除掉,而属性值也会去除开头和结尾的空白字符。
赋值
可以使用"="或者":"进行赋值。
值连接
使用"+="连接同名属性的值(以逗号分隔)。
注解
从";"或者"#"开头到行的结尾来注解。
转义符
使用"\"作为转义符,对字符进行转义(例如 "\#"代表了字符"#","\\"代表"\")。
多行的值(Multi-line values)
如果"\"作为行的连接符,表明下一行仍然是属性的值。
特殊字符
\\uXXXX将被编译为字符,同样\t,\r,\f也会编译为字符。
多行值(Multiline values)
使用三引号作为一种方便的形式来定义多行的值。
注:三引号的语法是一对连续的单引号或者双引号(通常都是成对的用)。
三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。
基本用法
Props的使用非常简单。概况的说,Props管理着属性。
Props p = new Props();
p.load(new File("example.props"));
...
String story = p.getValue("story");
Props加载属性的方法有多种形式:文件、输入流、字符串、属性Properties。然后通过Props的etValue方法来调用属性值,这个方法通常返回一个字符串的值。
分区
分区和INI文件的分区非常相似。在Props中,分区仅表示前缀相同的一组键,这组键直到分区结尾或者文件结尾。
分区名称已[开头,以]结尾。属于该分区的属性在分区的头部之后。分区名称将作为前缀加到分区属性中。分区以空的[]结尾或者新的分区开始或者到文件尾部。
示例如下:
[users.data]
weight = 49.5
height = 87.7
age = 63
[]
comment=this is base property
下面的和上述示例等同:
users.data.weight = 49.5
users.data.height = 87.7
users.data.age = 63
comment=this is base property
因此,分区可以缩短文件,从而使文件更可读。
Profiles
通常情况下,一个应用有不同的环境,因此要求不同组别的属性。例如web应用的测试环境、发布环境。一种组织这些属性的方法是定义不同的profile,在这些profile里同样的键有不同的值。
Props支持属性的Profile。Profile定义在键名内:profile名称以<>包装。一个可以可以有一个或者多个profile定义。同样,profile可以定义在键名的任意地方,甚至在单词的中间;然而,最好还是把它放到键名的尾部。
没有profile的属性是基于属性的,若检索特定profile的属性失败,将会检查基本的属性。
profile可以看着相同属性组的一个“不同的视图”或者“快照”。示例:
db.port=3086 db.url<develop>=localhost
db.username<develop>=root db.url<deploy>=192.168.1.101
db.username<deploy>=app2499
在上面的示例中,定义了3个键,两个键拥有两个不同的profile(develop/deploy)且没有基本的值。
上文提到,分区是一个键的前缀定义,并且profile可以定义在键名的任意地方,因而分区名称也可以包含profile定义,上述的示例可以改造如下:
db.port=3086 [db<develop>]
url=localhost
username=root [db<deploy>]
url=192.168.1.101
username=app2499
当检索上述值时,可以指定活跃的profile:
String url = props.getValue("db.url", "develop");
String user = props.getValue("db.username", "develop");
注意:一个profile可以同时定义多次。profile的顺序非常重要!当键定义到多个活跃的profile时,将返回第一个的值(第一个匹配的profile的值)。
你也可以仅仅检索基本属性(忽略profile)--使用getBaseValue()方法。基本属性不属于任何profile。
默认的活跃profile
通常,在一个应用的生命周期中,只有一组profile是活跃的。不需要每次在调用getValues()时都传递此活跃的profile。Props支持在外部定义这个所谓的活跃profile,这个定义在加载属性的props文件中。
在使用getValue(String)检索属性时,活跃的profile就是默认的profile。活跃profile以@profiles的特殊属性键定义。例如:
key1=hello
key1<one>=Hi! @profiles=one
则下面的java代码:
String value = props.getValue("key1");
将会返回值“Hi!”,因为活跃profile是"one".
活跃profile也可以通过java代码设置,方法是:setActiveProfiles()
.
内部profile
有这样一种场景:两个或者多个profile共享大部分配置,而只有很少一部分属性是不同的。为避免在每个profile中重复定义所有的属性,可以使用内部profile定义哪些不同的属性。Props首先检索内部profile的键,然后检索基本属性,示例如下:
key1<one>=Hi!
key2<one>=...
....
key100<one>=... key1<one.two>=Hola!
上述示例定义了两个profiles,第一个名称为"one",包含了100个键值对。第二个profile是一个名称为one.two的内部profile。它包含一个属性(key1)---但上层profile所有属性都是可用的!当使用java代码调用上述属性:props.getValue("key1", "one.two")时将会怎样呢?
Props将会
在内部名为one.two的profile中检索属性
如果没有找到,Props检查上一层的profile:one。
如果还检索不到,没有更上一层的profile了,Props检索基本属性。
内部profile可用有很多层。
宏
Props最大的优点是支持宏。宏是一些键值的引用,别的键可用使用该值。宏以{}包装。示例如下:
key1=Something ${foo}
...
foo=nice
key1的值是“Something nice”。宏可用引用任意存在的属性键,不管它们定义在哪里。
同样也支持嵌套的宏,示例如下:
key1=**${key${key3}}**
key3=2
key2=foo
key1的值是"**foo**".
宏和profile
宏通常使用当前活跃或者提供的profile来解析。若当前的profile改变了,宏的值通常也会改变。
这种行为由标志位useActiveProfilesWhenResolvingMacros来控制。例子如下:
root=/app
root<foo>=/foo
data.path=${root}/data
data.path的值在profile设置为active时是多少?因为foo是活跃的,root的值变为/foo,因此data.path的值为/foo/data.
若我们关闭所有的profile而只使用基本属性,data.path的值时/app/data.
也可以显示的设置宏的profile:
root=/app
root<foo>=/foo
data.path=${root<foo>}/data
上述例子中,宏root将一直使用foo profile而不管当前选定的profile,因而data.path的值将一直是"/foo/data".
多行值
多行的值可以通过三引号定义。中间的都看做值:
email.body='''
Hello $n, welcome!
'''
注意:多行的值的空白将不会对剪短!因此上述示例中的值将包含5行。
遍历和键的顺序
Props中的键是有顺序的!因此可以根据属性文件中键的顺序遍历所有的键。不用如下代码:
foo.1=value1
foo.2=value2
...
你可以遍历props如下:
Props props = ....
Iterator<PropsEntry> it = p.iterator();
遍历的顺序和props定义的顺序一致。
更进一步,可以通过增加profile来过滤检索或者/和分区遍历。你可以这样写:
Iterator<PropsEntry> it = p.entries()
.section("one.two")
.profile("prof1", "prof2")
.iterator();
上述代码仅仅遍历给定分区和给定profile的属性。
由于引入了profile,可以将一个键定义在属性文件的多个地方。例如,你可以为两个不同的profile定义一个特定的值。在这种情况下,将不能确定键的正确顺序:是第一个检索到的键还是它所在位置获取的值?你可以通过使用skipDuplicatesByValue和skipDuplicatesByPosition()来控制。
复制操作符
假定你有一定数量的属性,即默认情况下,和不同种类的数目一样,示例如下:
com.jodd.action1=value1
com.jodd.action2=value2
...
org.jodd.action1=value1
org.jodd.action2=value2
...
net.jodd.... # etc
Props支持你使用复制操作符(<=)来最小化重复的属性,上述属性可以写成如下形式:
[actions]
action1=value1
action2=value2
... []
org.jodd <= actions [com]
jodd <= actions [net.jodd]
<= actions
上述示例显示了使用复制操作的三种不同方法,没有使用分区,使用部分分区和完全使用分区。使用这三种方法的哪一种都可以,你可以任意选择一种。
注意:复制的值设置为宏,因此上述所有复制的属性也等同于:
org.jodd.action1=${actions.action1}
com.jodd.action1=${actions.action1}
....
配置
使用几种配置设置可以很好的对Props进行调优:
新行转义值
当行结尾符(EOL)需要转义时,指定一个新的字符串。默认值是空的字符串,故多行的值和单行的值连接起来。如果新行转义值被设置为,例如"\n"时,多行的值将以多行的形式保存。
截左侧值
如果需要从左边剪断的话,设置此值。
截右侧值
如果需要从右边剪断的话,设置此值。
新行忽略前面的空白值
若值分割为多行(以转义EOL)时需要忽略主要的空白值时定义此值。默认值时true,因此下面的多行属性:
key1=line1\
line2\
line3
将被读成line1line2line3(连接成的)
跳过空的属性
跳过空的属性的标志位。
连接重复的属性
一旦设置,重复的属性键将不会覆盖旧的键,而是连接并且通过逗号分隔。
多行值
默认启用,利用一种更便利的方式来书写多行的值,以三引号(和python一样)来书写。三引号内的所有字符认作一个值,因此新行不需要转义。
源码如下:
/**
* Value that will be inserted when escaping the new line.
*/
protected String escapeNewLineValue = StringPool.EMPTY; /**
* Trims left the value.
*/
protected boolean valueTrimLeft = true; /**
* Trims right the value.
*/
protected boolean valueTrimRight = true; /**
* Defines if starting whitespaces when value is split in the new line
* should be ignored or not.
*/
protected boolean ignorePrefixWhitespacesOnNewLine = true; /**
* Defines if multi-line values may be written using triple-quotes
* as in python.
*/
protected boolean multilineValues = true; /**
* Don't include empty properties.
*/
protected boolean skipEmptyProps = true;
参考文献:
http://jodd.org/doc/props.html
简约之美jodd--props属性使用的更多相关文章
- 简约之美Jodd-http--应用一箩筐
Jodd-http是一个微型的.简约的http client,然而简单而且方便.使用它可以轻松的实现发送请求和读取响应.它的目标就是日常应用变的非常简单,从而简化开发人员的工作. 了解Jodd-htt ...
- React(六)Props属性
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变.这就是为什么有些容器组件需要定义 state 来更新和修改数据. 而子组件只能通过 pro ...
- React系列之--props属性
版权声明:本文为博主原创文章,未经博主允许不得转载. PS:转载请注明出处作者:TigerChain地址:http://www.jianshu.com/p/fa81cebac3ef本文出自TigerC ...
- 创建组件的方法,组件的props属性、state属性的用法和特点,父子组件传值,兄弟组件传值
1.创建组件的方法 函数组件 class组件 1.1 函数组 无状态函数式组件形式上表现为一个只带有一个 `render()` 方法的组件类,通过函数形式或者 `ES6` 箭头 `functi ...
- Vue.js 源码分析(十三) 基础篇 组件 props属性详解
父组件通过props属性向子组件传递数据,定义组件的时候可以定义一个props属性,值可以是一个字符串数组或一个对象. 例如: <!DOCTYPE html> <html lang= ...
- React创建组件的方法,组件的props属性、state属性的用法和特点,父子组件传值,兄弟组件传值
创建组件的方法,组件的props属性.state属性的用法和特点,父子组件传值,兄弟组件传值 1.react组件 1.1.创建组件的方法 1.1.1.函数组件 定义一个组件最简单的方式是使用JavaS ...
- 组件的props属性和state状态
props属性: 我使用代码来说明React中props属性: // Profile.jsx import React from 'react' ; export default Class Prof ...
- Vue2.0 【第二季】第7节 Component 组件 props 属性设置
目录 Vue2.0 [第二季]第7节 Component 组件 props 属性设置 第7节 Component 组件 props 属性设置 一.定义属性并获取属性值 二.属性中带' - '的处理方式 ...
- 组件通过props属性传值
组件之间的传值 组件是一个单独功能模块的封装,有属于自己的data和methods,一个组件的 data 选项必须是一个函数 为什么必须是函数:因为只有当data是函数时,不同实例调用同一个组件时才会 ...
随机推荐
- 配置TL-WVR45G企业路由动态地址
1.打开浏览器,在地址栏输入http://192.168.1.1. 2.输入默认用户名密码:admin,登录. 3.[基本设置]->[lan设置]->[lan设置] ip地址改成:192 ...
- 网页加速之Chromium 预载入 Prerendering
前一篇博文已经介绍通过prefetch预先载入网页的资源来提升网页载入速度,以下我们一起来看一下网页加速之chromium prerendering.在介绍prerendering之前,先介绍两个概念 ...
- HDOJ 5098 Smart Software Installer 拓扑排序
拓扑排序: 两个队列,一个放不须要重新启动入度为0的,一个放须要重新启动入度为0的....从不须要重新启动的队列開始,每弹出一个数就更新下入度,遇到入读为0的就增加到对应队列里,当队列空时,记录重新启 ...
- JNI 实战全面解析
项目决定移植一款C++开源项目到Android平台,开始对JNI深入研究. JNI是什么? JNI(JavaNative Interface)意为Java本地调用,它允许Java代码和其他语言写的代码 ...
- Spring MVC 注解式
1.注解式控制器简介 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类.已经@Deprecated. 二.Spring2.5引入注解式处理器支持,通 ...
- BZOJ 4003 左偏树
思路: 用到了左偏树合并复杂度是logn的性质 一开始先BFS一遍 打标记的左偏树 //By SiriusRen #include <cstdio> #include <cstrin ...
- linux下支持托盘的邮件客户端Sylpheed
在网上搜索了很多客户端想支持系统托盘,发现一个很不错的邮件客户端Sylpheed.设置方式和foxmail很像,最为重要的是支持系统托盘,很方便,默认没有开启,简单设置下:配置->通用首选项-& ...
- Vijos——T1406 拉力赛
https://vijos.org/p/1460 描述 车展结束后,游乐园决定举办一次盛大的山道拉力赛,平平和韵韵自然也要来参加大赛. 赛场上共有n个连通的计时点,n-1条赛道(构成了一棵树).每个计 ...
- 从2014年D2前端技术论坛看前端发展趋势
上周六有幸參加了在杭州阿里巴巴西溪园区举办的2014年D2前端技术论坛和晚上的酒会.实地感受了一下阿里巴巴前端开发的技术氛围和影响力.整体上看这次D2规模还是挺大的,国内前端的知名大牛基本上都到了. ...
- 手动连接数据库(jdbc)
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...