=======================
原文
=========================
为了方便群中的
Play
初学者们,写了一篇入门引导,以帮助初学者尽快了解
Play
。本文之前发在另一个网站,因为觉得有些不便,还是转到博客上。
欢迎来到
play
的世界,在这里你将体验到与传统
SSH
开发网站不一样的感受。我将把我学习
play
的感受与经验分享给大家,希望能对大家(特别是初学者)有所帮助。
Play
是一个非常有创造力、让人眼前一亮的
Java web
开发框架。它把网站开发中常见的繁琐的任务,以各种突破常规的方式简化,
"
不要重复你自己
"
,让人在开发过程中有一种享受的感觉。使用
Play
实现功能,有时候简单地让人难以相信(对于长期使用
SSH
的人来说尤其明显)。
在
play
的
google group
中,曾经有人说,当地要举办一次编程大赛,他将使用
play
参赛。每个参赛队可使用任何语言和框架,在
6
小时内实现指定的功能。结果他们胜利了,打败了
Ruby on rails
队。使用
Play
开发网站,在不使用各种第三方插件的情况下(
Rails
强项),开发效率与
Rails
在同一级别。
这里将介绍一些最让我印象深刻的特性:
修改不用重启
:这是
play
最为吸引人的一点。修改任何
java
或模板代码,都不需要重启
server
,直接在浏览器中刷新即可看到最新效果。这曾是多少
Javaer
梦想的功能。结合
livereload
等工具,可以实现光标不离开编辑器就能实时看到最终页面效果的功能。
内置基于
netty
的
web
服务器
:
play
内嵌了基于
netty
的高性能服务器,只需要一条命令即可运行起来,简单而强劲,推荐使用。如果因为服务器限制而必须使用传统的
servlet
服务器的话,可将
play
程序打包为
war
部署。
Play
的版本
Play
当前的版本有点乱,不同版本之间差别还相当大,这常常让初学者一头雾水。
Play
目前可分为三个版本,它们之间没有谁比谁好,只有谁比谁适合。大家可根据自己的实际情况来选择合适的版本来学习。
首先是
Play
的成名之作:
Play1
Play1.x
是成名之作。它是一个
Java
开发框架,使用
python
作为构建系统。内置了
Jpa
(
Hibernate
)和基于
groovy
的模板系统。它大量使用了代码增强,提供了大量魔术般的功能,以提高程序员的开发效率和代码的简洁性。它编译速度快,代码简洁,让人开发时非常享受。
Play1
当前最新版本为
1.2.5
,它是三者间最为成熟的一个版本,拥有大量成熟的第三方模块供使用。这里值得一提的是群友
green
开发了大量基于
play1
的优秀插件,如
rythm/play-morphia
等,进一步提高了
play
的性能及开发效率。虽然
play1
目前已处于维护状态,但如果你需要在近期开发传统的信息管理类网站,它仍然是最佳选择。
关于
Play2
几个月前,
Play1
的开发者加入了
typesafe.com
,并且
play
作为其官方
web
框架。
typesafe
是一个力推
scala
的公司,所以新推出的
play2
,实际上是将
scala
作为第一开发语言的。比如
play2
中使用的新构建工具
sbt
,是
scala
的标准构建工具;
play2
中很多底层代码都是用
scala
写的,由
Java
来调用;
play2
的默认模板引擎,也是基于
scala
的。在
play2
中,处处可见
scala
的痕迹。但
play2
也同时提供了
java api
,以吸引广大的
Java
开发者。由于
Scala
与
Java
在语言特性与风格上的巨大差别,
play2-scala
与
play2-java
,在很多地方都不同。
play2
相对于
play1
,不是一次简单的版本升级,而是几乎重写了全部代码。
Play2
与
Play1
在很多方面都不同,不能通用。也许它本来就不该叫
play2
的,它与
play1
的区别,如同
struts2
与
struts1
的区别
(struts2
其实是由另一个叫
webwork
的框架改名而来
)
。
Play
开发团队从商业利益上的考虑作出的决定(以及某种程度的不负责任),曾经在
play
社区中引起激烈争论,大批
play1
用户表达了自己的不满和对
play2
的失望。
Play2
在开发风格上与
Play1
有所不同。如同
typesafe
公司名称所示,
Play2
在最大程度的利用编译器的检查,以求更加稳定可靠。在
Play1
中一些追求简洁的魔术代码,在
Play2
中取消了,相反要使用一些略显繁琐的代码来实现相同功能。同时因为
scala
相当慢的编译速度,让热修改后生效的时间大大延长,有时候难以忍受(在
play1
中
1
秒以内,
play2
中要
5
秒以上)。所以很多从
play1
转向
play2
的用户都非常不适应,拒绝转向
play2
。
由于
Play2
的仓促推出,当前的
2.0.2
版不论在功能上还是稳定性都存在相当多的问题,插件生态系统也没有成熟(
Play1
的插件不能在
Play2
上使用)。所以当前直接在生产系统中使用它还是有一定风险的,最好再等几个月。
不论如何,
Play2
是官方支持,目前所有的开发活动都基于它,它是未来的趋势。它重新组织的代码结构与
API
,相比
1
来说,也要精致很多。相信现在存在的各种问题在未来会慢慢解决,只是需要一段时间。
Play2
的卖点是并发,因为它底层使用了
scala
中的
akka
库,对于开发实时网站程序比较有优势。但对于传统的信息系统类网站,也许
Play2
很难达到
Play1
的程度。个人认为,对于以开发信息系统为主的团队,使用
Play1
在各方面来讲,都会是更好的选择。
对于认为新版一定好于旧版,或敢于尝鲜而选择了
Play2
的朋友,马上要面临一个新的问题:
是用
Play2-Scala
还是
Play2-Java
呢?
个人认为,这个选择还是比较简单的。如果你是
Scala
程序员,来寻找
Scala
下的
web
框架,就选
Play2-Scala
。它比
lift
简单易学,容易上手。如果你是
Java
程序员,或者主要以
Java
项目为主,请选择
Play2-Java
。
虽然
Scala
在宣传上总是以
"
更好的
Java"
来作为卖点,但它实际上是一门与
Java
相差非常大的语言。在语言风格上,
Scala
融合面向对象与函数式,强调数据的不变性,这都与
Java
不同。在难度上,
Scala
要比
Java
难很多,函数式编程和类型系统会让很多
Java
程序员止步,通常在六七年的编程经验后再学习
Scala
是比较靠谱的选择。
另外,虽然两者都是
JVM
上的语言,但它们之间是有缝的,调用对方的库经常会遇到各种各样的问题。比如你想在
Scala
上使用
java
的
jpa/ebean/morphia
等,会非常麻烦。但
scala
自己又没有一个足够成熟好用的
orm
,这可能是阻止你使用
Play2-Scala
的一个重要原因。
所以,还是如前面所说,
Scala
程序员选
Play2-Scala
,
Java
程序员选
Play2-Java
。
Play2-Scala
Play2-Scala
相对于
Scala
上的另一个成熟
web
框架
lift
来说,优势在于简单易学、有
typesafe
官方支持,前途光明。同时对于以
restful api
作为主要目的的程序来说,
Play2
提供的
routes
相当好用。劣势在于不如
lift
成熟,生态系统不如
lift
。在某些时候,
Play2
的
MVC
不如
Lift
的
View-First
好用。
Play2
使用了
sbt
,底层是
akka
,模板层基于
scala
,
orm
是
Play
自己开发的一个叫
anorm
的持久层。
anorm
的特点抛弃
orm
,直接使用
jdbc
,使用预定义的
parser
把结果集转为对象。
Anorm
初看起来比较吸引人,但在实际使用过程中,异常繁琐。对数据库字段的一次修改,往往要牵扯到几个地方,动不动就出错,同时再加上
scala
奇慢无比的编译速度,极易让人心情烦躁。所以也有人尝试在
play2
中使用
squerl
,好在很容易集成。当然还是让我们期待
typesafe
正在开发的新
orm:slick
。
对于
Scala
程序员来说,
Play2-Scala
是一个比较好的选择,不妨一试。
注意,如果你使用
Play2-Scala
,想使用
Play2
中提供的
JPA/Ebean
时请小心。由于
Play2
在代码增强时,只增强
Java
代码,这将导致从
Scala
中调用它们时出现问题,所以最好选择
scala
中的
orm
。
Play2-Java
对于
Java
程序员来说,还是用
Play2-Java
比较顺手。虽然相比
Play1
要繁琐一些,但对于
SSH
等,还是要简洁很多。
Play2
中
Java
的
api
与
Scala
的
api
不在同一个包下,要注意不要引用错了。
对于
controller
和
action
,
Play2
与
play1
的结构基本相同,依然采用静态方法,但需要返回一个
Result
。注意的是,
Action
中的参数,只能匹配在
routes
中的
url
定义中出现的参数,而不像
play1
那样,还能匹配任意
query
参数和
post
参数。
Orm
方面,同时提供了
JPA(hibernate)
和
Ebean
。我个人比较推荐
Ebean
,相对于
hibernate
,它的
api
更加简单,不易出错,因为它是用
jdbc
的思路。在官方下载包里有一份
100
多页的
pdf
文档,看完就差不多了,用起来麻烦绝对比
hibernate
少太多。我在
Play1
中就通过第三方的插件使用
Ebean
,效果很好。也许只有一种情况不能用它,因为它不支持
sql server
。
Play2
基于
scala
的模板层,对于
Java
开发者来说是不太方便的。两点原因:
Scala
的语法与
Java
不同,虽然在模板中已经尽量简化了,但难免还是会遇到一些不好下手的问题。
模板将被转化为
Scala
代码进行编译。如前文所说,
Play2
对于
Scala
代码不会进行增强,所以在模板中调用
Java
类可能会有问题。比如直接调用
@user.articles
,它不会像在
Java
中那样被替换为
user.getArticles
,而是直接调用
user.articles
字段。由于代码增强通常是在
getter/setter
上进行的,所以这样可能拿不到数据。如果想解决此类
lazy loading
的问题,我们必须在
model
中使用传统的
javabean
方式显式声明
getter/setter
,然后在模板层中调用
@user.getArticles
,相当繁琐。
所以在
Play2
官方推出基于
java
的模板前,我推荐使用两个第三方模板插件。一是
faster groovy template
,二是
japid
,它们都已经支持
Play2
,且不会有上述问题(
Japid
待测)。
另外,对于不喜欢
Java
语法但又不想用
scala
的同学,可尝试
xtend
。
xtend
代码要比
Java
舒服一些,而且直接生成
java
源代码,不存在编译等问题。
Play
存在的问题
虽然
Play
在很多方面给我们带来的方便,但难免也会有一些问题需要注意,这里简单提一下。
Play1
Play1
主要存在的问题有三个:
与某些第三方库结合使用时,必须写插件。比如
morphia, ebean
等。因为
Play1
需要对我们的
Java
源代码进行增强,而这些库也需要对字节码进行增强。如果不写插件处理
classloader
及字节码,会出现无法运行的情况。