如何使用tapestry-prop提高Tapestry运行效率?
如何使用tapestry-prop提高Tapestry运行效率?
tapestry-prop介绍
它是一个为Tapestry4.0编写的扩展包,提供了一个新的绑定前缀"prop:"。这个前缀用于获取页面或组件的属性。
看上去和Tapestry内置的"ognl:"前缀没有什么区别,但是低层实际获取数据的方法和OGNL是完全不同的。它采用了字节码生成的方式去获取用户类中的那些可以通过名字获取的属性。
"prop:"前缀只能获取简单属性或者由路径代表的属性(一串用点号隔开的属性名)。比方说 "prop:userName" 或 "prop:identity.admin"。
最后一个属性如果是只读或只写的话,在分别对它们更新或读取的时候就会抛出一个适当的异常。
Tapestry5将默认使用更成熟的"prop:"前缀(OGNL还会保留,但是到写这篇文章为止还没有完成)。
使用
所需做的只是将tapestry-prop包放在类路径下就可以了(典型的,在WAR包的WEB-INF/lib包下)。Maven会为你作好剩下的一切,你要做的仅仅是把 tapestry-prop作为一个项目的一个依赖包。
你可以在HTML模板里面使用"prop:"前缀:
<span jwcid="@Insert" value="prop:userName">Joe User</span>
或者,你也可以在页面或组件的定义文件里面使用:
<component id="userName" type="Insert">
<binding name="value" value="prop:userName"/>
</component>
这个包使用JDK1.3编译,并与其兼容。
与OGNL比较
"prop:"前缀比"ognl:"高效,但是不像它那样灵活。
优势是,使用它对性能将会有极大的提升。不仅没有了反射的开销,而且也不会有OGNL操作时需要的临时对象的创建。
缺点是,OGNL总能正确的计算属性的类型。"prop:"前缀使用的是申明的类型,就想编译时被编译过的Java 代码一样。如果一个页面属性使用接口定义的,那么你不能用这个接口的实现来获取属性(除非那些方法也是用接口定义的)。
OGNL还包含了丰富的类型转化系统和更丰富的语法。正是OGNL的这种简单和高效(注:不是指运行效率)使它被Tapestry选用而不依赖于代码生成的原因。
在性能方面,有了一个显著的提高:
上图显示了在处理简单情况(简单属性)和复杂情况(属性路径)下get操作循环次数。数字越高表面性能越好(在2秒内的循环次数)。
使用纯粹的java代码和使用"prop:"前缀效率几乎是并驾齐驱的,ONGL就有了明显的差距。更糟的是,每一个包含在ONGL表达式里的条件都会有巨大的影响(相反,另外两种情况下,额外的条件几乎没有影响)。考虑到这些因素,在成百上千的Tapestry页面里面差距就非常明显了。
默认使用"prop:"绑定
使用Tapestry的配置属性org.apache.tapestry.default-binding-prefix可以使页面或组件的默认绑定规则使用"prop:"。比如:
<page-specification>
<meta key="org.apache.tapestry.default-binding-prefix" value="prop"/>
. . .
</page-specification>
意思是在所有页面定义的值如果没有使用明确的前缀则会默认的使用"prop:"而不是& quot;ognl:"。如果把<meta>标签一道应用的定义文件(application specification),则会影响到应用中所有的页面和组件。
下载
beta版的包现在可以在Maven 2 库里下载到http://howardlewisship.com/repository/