Play framework横空出世

09-10-21 banq
颠覆臃肿的JavaEE开发框架(bloated Enterprise Java stacks)的Play框架1.0发布,它在很多方面有其革命性的独创,也有助于我们了解现在JavaEE框架的不足。

Play框架吸收PHP RUBY动态语言的特点,采取即时源码编写,即时激活,框架本身融合了编译器和服务器。取代了 compile-package-deploy 过程,提高产品的开发效率。Play框架甚至提供在线编辑器,在线修改BUG后即时投入应用。

架构有如下特点:

1. Simple stateless MVC architecture 简单的无状态MVC架构

Play框架认为一边是数据库保存状态,一边是浏览器也可以保存状态,那么还要中间件MVC保存Session状态干什么呢?

HttpSession有很多问题,虽然可以处理针对某个用户的状态,但是万一用户中途离开怎么办,HttpSession对资源消耗,以及在可伸缩性方面是有问题的。

Play框架秉承share nothing架构思想,不再象黑客那样破解原本自然正常Http模型,然后强行植入状态,无状态架构可以并行同时输出多个页面,提高Web性能。

2 。HTTP-to-code mapping

众所周知的Servlet API 和Struts其实是扭曲的,使用奇怪的API将Http协议隐藏起来,Play框架认为一个Web应用框架应该给用完整的 直接的对Http调用和使用,这其实就是RESTFul精神。

这样 URI是play framework的主要概念。

对一个Java对象的调用,不是写Java语句,而是使用URI就可以,如下:

GET /clients/{id} 实际是调用Clients对象的show方法。

3.Efficient templating engine

Play框架认为JSP & Expression Language模板机制很好,但是需要太多配置,吸收其模板设计,剔除配置。对于一个有无Email的显示页面,使用JSP大概需要以下很多语句实现:

<c:choose>
    <c:when test="${emails.unread != null && fn:size(emails.unread)}">
        You have ${fn:size(emails.unread)} unread email(s)!
    </c:when>
    <c:otherwise>
        You have no unread emails!
    </c:otherwise>
</c:choose>
<p>

而是要Play框架则可以如下:

You have ${emails.unread ?: 'no'} ${emails.unread?.pluralize('email')} !

4.JPA on steroids

Play框架采取JPA作为持久化,并且使其更方便使用。

public void messages(int page) {
    User connectedUser = User.find("byEmail", connected());
    List<Message> messages = Message.find(
        "user = ? and read = false order by date desc",
        connectedUser
    ).from(page * 10).fetch(10);
    render(connectedUser, messages);
}
<p>

个人意见:这段代码倒是直接将持久层和表现层直接耦合在一起,没看到Domain Model了。看来DDD需要普及到每个角落不容易啊。

5.Integrated Cache support, with easy use of the distributed memcached system if needed.

整合了缓存支持,可以使用memcached作为分布式缓存。

6.融入了OpenID 这样单点登录SSO技术。

7.提出Application modularization,可以重用各种组件,包括CSS Javascript

个人点评:总体来说,Play框架是一个与Struts2 JSF Tapestry竞争的框架,但是又整合了持久层和服务器,它的强项在其前半部,也就是展现层,作为一个打包整合的框架,没有强大的Domain层,是非常令人失望的。

Play框架网站:

http://www.playframework.org/

[该贴被banq于2009-10-21 10:23修改过]

12
lei55022033
2009-10-22 10:27
java不需要新框架了,只需要好框架。框架的增多,只会增加学习的难度,让Java更快的走向死亡。

lgx522
2009-10-22 13:09
同道们测过play的性能吗?

浏览了一下tutorial,感觉比Grails还省事。

如果性能好的话,大家就可以跟进了(Rails开发虽省心,布署太烦了,语言应用范围也有限)。

arden
2009-10-23 12:27
至于Domain层不强大,这个是迟早的问题~~

lazytalent
2009-10-23 13:06
框架框架框架框架框架框架

框架                      框架

框架       程序员        框架

框架                      框架

框架框架框架框架框架框架

[该贴被lazytalent于2009-10-23 13:11修改过]

saharabear
2009-11-21 12:55
用Play还不如用脚本语言去.我的观点是Java就应该用在适合的地方,而不需要让Java去追求ROR.其实Java要做到ROR的开发速度也不难,Java提供的反射,性能已经足够好了,简单的几个Java类实现约定大于配置也不难.问题在于,Java的优势是做大一点的项目,如果用脚本类的语言去做足够大的项目,维护过程会让人头疼.

Java的分层,领域模型才是更好的方式.

当然,Play这一类的,我想也包括Grails,适合只懂Java,对其他脚本没兴趣的程序设计师去开发小一点的东西.

wind13
2009-12-15 17:42
个人觉得Play最大的特点是很容易上手,RESTFul的精神,无状态(Share nothing)的理念。banq说没有强大的Domain层,我不是太理解,因为Play里是有Model的,可以继承它提供的Model,然后就会有很多现成的静态方法可以用,如User.save()等,也不算贫血模型,不过另外有个贴子说Play的背后实现机制有点“暴力”,这个我没有看源码也不是很清楚,但这种实现绝对是用户所喜欢的,如果不得已用了“暴力”,那是因为Java的本身的不足,只要不影响系统稳定性和执行效率,封装好地“暴力”一下也可以接受。

而且,现在新的版本将支持Scala语言特性,也就是说有了函数式编程的很多优势,这样使得代码更加简洁和高效,或者你也可以选择支持LambdaJ,也是同样的简洁和高效。

所有这些,的确让人兴奋啊!

oojdon
2010-01-06 23:07
2009年12月15日 17:42 "wind13"的内容
不过另外有个贴子说Play的背后实现机制有点“暴力”

我贴一段它的“暴力”代码:

    protected static void renderText(CharSequence pattern, Object... args) {
        throw new RenderText(String.format(pattern.toString(), args));
    }
    /**
     * Return a 200 OK text/xml response
     * @param xml The XML string
     */
    protected static void renderXml(String xml) {
        throw new RenderXml(xml);
    }
    /**
     * Return a 200 OK text/xml response
     * @param xml The DOM document object
     */
    protected static void renderXml(Document xml) {
        throw new RenderXml(xml);
    }
    /**
     * Return a 200 OK application/binary response
     * @param is The stream to copy
     */
    protected static void renderBinary(InputStream is) {
        throw new RenderBinary(is, null, true);
    }
    /**
     * Return a 200 OK application/binary response with content-disposition attachment
     * @param is The stream to copy
     * @param name The attachment name
     */
    protected static void renderBinary(InputStream is, String name) {
        throw new RenderBinary(is, name, false);
    }
    /**
     * Return a 200 OK application/binary response
     * @param file The file to copy
     */
    protected static void renderBinary(File file) {
        throw new RenderBinary(file);
    }
    /**
     * Return a 200 OK application/binary response with content-disposition attachment
     * @param file The file to copy
     * @param name The attachment name
     */
    protected static void renderBinary(File file, String name) {
        throw new RenderBinary(file, name);
    }
    /**
     * Render a 200 OK application/json response
     * @param jsonString The JSON string
     */
    protected static void renderJSON(String jsonString) {
        throw new RenderJson(jsonString);
    }
    /**
     * Render a 200 OK application/json response
     * @param o The Java object to serialize
     */
    protected static void renderJSON(Object o) {
        throw new RenderJson(o);
    }
<p>

render result都是通过运行时异常抛出。

[该贴被oojdon于2010-01-06 23:08修改过]

sdslnmd
2011-10-21 11:19
请教一个神奇的问题 我用play 然后在action的方法中调用form中的传来VO对象。 如果是public void方法 就会堆栈溢出 如果是private void 就没有问题 。如果有返回类型,就跳转页面到了这个私有的方法=,但是这里是没有页面可以显示的。 这是为什么?

zhanbocn
2012-03-29 11:32
史上最快Java Web framework JFinal横空出世

JFinal 是基于Java 语言的 web 开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python等动态语言的开发效率。

JFinal有如下主要特点:

l MVC架构,设计精巧,使用方便简单

l 遵循COC原则,零配置,无xml

l ActiveRecord支持,使数据库开发极致快速方便

l 自动加载修改后的java文件,开发过程中无需重启web server

l AOP支持,拦截器配置灵活,使用简单

l Plugin体系结构,扩展方便

l 多视图支持,支持FreeMarker、JSP、Velocity

l 强大的Validator后端校验功能

l 功能齐全,拥有struts2的绝大部分功能

l 体积小仅150K,且无第三方依赖

项目首页:http://code.google.com/p/jfinal

以下是一个Blog管理的示例程序:

1:控制器(支持FreeMarker、JSP、Velocity、Json等等以及自定义视图渲染)

01

@Before(BlogInterceptor.class)

02

public class BlogController extends Controller {

03

public void index() {

04

setAttr("blogList", Blog.dao.find("select * from blog order by id asc"));

05

}

06

07

public void add() {

08

}

09

10

@Before(BlogValidator.class)

11

public void save() {

12

getModel(Blog.class).save();

13

index();

14

}

15

16

public void edit() {

17

setAttr("blog", Blog.dao.findById(getParaToInt()));

18

}

19

20

@Before(BlogValidator.class)

21

public void update() {

22

getModel(Blog.class).update();

23

index();

24

}

25

26

public void delete() {

27

Blog.dao.deleteById(getParaToInt());

28

index();

29

}

30

}

2:Model(仅一行代码,且无xml,无annotation,中间的new Blog()代码也可省去)

1

public class Blog extends Model<Blog> {

2

public static final Blog dao = new Blog();

3

}

3:Validator(API引导式校验,比xml配置方便N倍)

01

public class BlogValidator extends Validator {

02

protected void validate(Controller controller) {

03

validateRequiredString("blog.title", "titleMsg", "请输入Blog标题!");

04

validateRequiredString("blog.content", "contentMsg", "请输入Blog内容!");

05

}

06

07

protected void handleError(Controller controller) {

08

controller.keepModel(Blog.class);

09

10

String actionKey = getActionKey();

11

if (actionKey.equals("/blog/save"))

12

controller.render("add.html");

13

else if (actionKey.equals("/blog/update"))

14

controller.render("edit.html");

15

}

16

}

4:拦截器(本拦截器仅输出文字到控制台,仅是用法示例,本程序可以不需要)

view sourceprint?

1

public class BlogInterceptor implements Interceptor {

2

public void intercept(ActionInvocation ai) {

3

System.out.println("Before invoking " + ai.getActionKey());

4

ai.invoke();

5

System.out.println("After invoking " + ai.getActionKey());

6

}

7

}

JFinal QQ群:222478625

下载demo在这里 http://www.oschina.net/p/jfinal 点击“软件下载”按钮即可

猜你喜欢