Play源码深刻之七:Play的MVC实现

总体来讲,Play1.x是一个较完善的框架,各类功能都包罗万象,有点像句老话“麻雀虽小五脏俱全”哈。虽没有Struts、SpringMVC的大名气,可是使用起来,至关顺手。本文将深刻Play1.x的MVC,也整合前面各方知识。 java

在new一个Play项目以后,都会有models、views、controllers三个文件夹,正好对应MVC,并且每类文件还必须放对地方。spring

这里要讲的是Play框架层面上,对MVC作的工做: json

M:Model(模型),在Model上,Play对每一个Model进行了加强,在PlayPlugin中,有enhaner事件,每一个插件均可以对Model进行加强,触发的时机在play.Invoker:run()中,调用init方法,检测play代码是否有变化,有变化就会发出加强事件,位置在play.classloading.ApplictionClasses:enhance()方法中。响应事件的有CorePlugin和JPAPlugin,JPAPlugin在前文已经说过,是织入JPA支持方法,而CorePlugin的enhaner有多个加强类,全在play.classloading.enhancers包中。 服务器

 QQ20150803-2@2x 

Model采用的ActiveRecord比POJO/DAO/Service高明,以前作SSH项目时,早就烦透了写一大片DAO/Service,并且里面尚未代码……(由于都集中到某个base类中)。而ActiveRecord没有这等烦恼,让人用着舒服~。 restful

V:Views(视图),Play模版引擎是使用Groovy语言,我用过Groovy,感受这货就是没法无天版的Java,吸收了各家所长,当模版引擎是小菜一碟。不过Play2已经放弃Groovy。 session

在play.mvc.results中能够看到各类返回结果,有Html/template/json/xml/text/binary。对于只想用play作移动端restful后台的项目,果断好用。 mvc

C:Controller(控制器),Play对比struts2的使用xml映射和springMVC的注解都要直接,使用routes文件,直观高效。 play会加载route文件,当请求过来时,进行匹配,若是没有找到就会404。框架

public class Router {
    public static Route route(Http.Request request) {
        ...
        for (Route route : routes) {
            Map<String, String> args = route.matches(request.method, request.path, request.format, request.domain);
            if (args != null) {
                request.routeArgs = args;
                request.action = route.action;
                if (args.containsKey("format")) {
                    request.format = args.get("format");
                }
                if (request.action.indexOf("{") > -1) { // more optimization ?
                    for (String arg : request.routeArgs.keySet()) {
                        request.action = request.action.replace("{" + arg + "}", request.routeArgs.get(arg));
                    }
                }
                if (request.action.equals("404")) {
                    throw new NotFound(route.path);
                }
                return route;
            }
        }
        ...
        throw new NotFound(request.method, request.path);
    }
}

Play使用Netty作服务器,没有使用j2ee一套,因此得本身实现request/respone/session等类,但Play的实现比j2ee的要灵活好用。dom

每次初始化调用相关准备后,Play就会使用Router中的路由进行请求分发。而返回结果是基于异常机制,这也是为人所诟病的。这一点在以前的 请求一章提过。 .net

play也有过滤器机制,前文也说过,play经过插件响应出完成过滤,这个机制在play 1.2.3上尚未看见。另外Play的before/after/with注解也有过滤器的做用。

相关文章
相关标签/搜索