總體來講,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包中。 服務器
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註解也有過濾器的做用。