01.Play框架最主要的概念
MVC應用程序模型
Play框架完全遵循MVC模式,MVC模式把應用程序分成幾個獨立的層:presentation表現層和model模型層,表現層進一步分成view呈現層和controller控制層。
- Model層是應用程序操作的特定領域展現的信息。領域邏輯把“領域的意思”添加到原始數據裏。許多應用程序使用持久存儲機制,比如數據庫來存儲數據。MVC不特別指明數據訪問層,因爲mvc模型能夠理解底層操作,或數據訪問層已經被模型進行了封裝。
- View 層把model層渲染到一個適當的交互窗體,如典型的用戶接口。 一個model可以有多個views,以實現不同的作用。在一個web應用程序裏,view通用渲染成web格式的內容,比如HTML, XML或JSON。然而,在某些情況下,view也可表示成二進制窗體,比如一個動態渲染的圖表。
- Controller 負責響應事件 (通常是用戶actions),並對這些事件進行處理,也可能是調用model的修改方法。在一個Web應用程序裏,事件特指http請求:一個專門用於監聽http請求的控制器,它從’事件’裏提取相關數據,比如查詢字符串參數,請求headers… 並把修改結果更新到底層model對象。
在Play應用程序裏,這三個層被分別定義到app目錄下的三個java包裏。
app/controllers
控制器就是一個java類,其中的每個public/static方法都是一個Action。一個action就是一個java入口點,當接收到一個http請求時,這個action就會被調用。控制器類裏的java代碼並不真正的面向對象的。Action方法從http請求中提取相關的數據,讀取或更新model對象,並向http請求者返回一個封裝好的response結果。
app/models
領域模型對象層(以下簡稱model)是一系列完全使用java面嚮對象語言特徵的java類,它包含了數據結構和數據操作。無論何時,model對象都需要存儲到持久化存儲設備裏,一般情況下他們或許還包含有一些jpa註釋和sql語句。
app/views
通過使用play提供的高效模板系統,可以生成大多數應用程序的views。控制器從model層獲得某些感興趣的數據,然後把這些數據應用到一個模板,並且通過模板把這些數據裝飾得非常漂亮。這個包由HTML, XML, JSON或其他特定用於動態生成model展現的模板文件組成。
請求生命週期
Play框架是一個完全的stateless框架,而且只面向request/response。所有的http請求都遵循以下過程:
- 一個http請求被框架接收。
- Router組件試着找到能夠接收這個請求的確切路由,相應的action方法隨後被調用。
- 應用程序代碼被執行。
- 如果需要生成一個複雜的view,那麼一個模板文件將會被渲染。
- acton方法的結果(http 響應代碼、內容)隨後被作爲http response發出。
標準應用程序佈局layout
應用程序佈局標準化是保持開發簡單化的保證。
app目錄
這個目錄包含了所有可執行的代碼:java源代碼和view模板。
我的.class文件去哪裏了?
請不要尋找編譯過的java類。框架只在運行時才編譯java源代碼,而且只會把編譯後類文件緩存到tmp目錄下。在play框架裏,可執行文件是.java源文件,而不是編譯後的類。
在app目錄下有三個標準包,分別對應mvc架構的三個層,你也可以添加你自己的包,如utils包。
另外,views包下,還可以有以下子包:
- tags, 主應用程序的標籤包,比如可重用的模板片段。
- 每個控制器的views文件夾–按照約定,每個控制器相關的模板都要存儲到他們自己的子包裏。
public目錄
存儲在public目錄的資源都是些可以直接被web服務器向外發佈的靜態資產。
這個目錄共分爲三個標準的子目錄:分別存儲images, CSS和JavaScript文件。 你應用試着像這個標準一樣組織你的靜態資產,以保持所有play應用程序的一致性。
默認情況下,/public目錄被映射到/public URL路徑,你也可以自行修改映射到其他目錄,甚至爲你的靜態資產使用多個目錄。
conf目錄
conf目錄包含了所有應用程序的配置文件。
這裏有兩個必須的配置文件,application.conf和routes:
- application.conf,應用程序最主要的配置文件。它包含了標準的配置參數。
- routes, 路由定義文件。
如果你需要增加一些特定配置選項,直接在application.conf中進行添加比較易於管理,文件的配置選項可在程序代碼中通過Play.configuration.get("propertyName")方法讀取。當你創建一個新的應用程序時,play new命令將從$PLAY_HOME/resources/application-skel/conf
目錄
複製一個默認的配置文件。
如果其他庫需要一個指定的配置文件,那麼請把將該指定的配置文件放到conf目錄(這個目錄是play指定的java 類路徑ClassPath),並在application.conf中用@include進行指定。
注意,這是一個尚處在試驗階段的特性,目前或許還不能正常工作。尤其是佔位符和框架id還不能正確處理這個特性。
比如,如果你在conf/mime-types.conf文件裏定義了一個附加的MIME類型:
# Web fonts
mimetype.eot = application/vnd.ms-fontobject
mimetype.otf = application/octet-stream
mimetype.ttf = application/octet-stream
mimetype.woff = application/x-font-woff
通過在application.conf文件裏添加下面這條代碼就可以把這些配置包含進來:
@include.mime = mime-types.conf
lib目錄
這個目錄包含了所有應用程序需要的標準java庫,他們會自動添加到java classpath裏。
開發生命週期
使用play進行開發,沒有編碼、打包或部署階段。然而,play通過兩種環境來執行這些過程:DEV模式用於開發階段,PROD模式用於部署階段。
關於DEV/PROD模式
應用程序可以運行於DEV或PROD模式。使用application.mode configuration可以進行切換。當運行於DEV模式時,play將檢查文件修改,並在必要的情況下重新加載程序。
PROD模式是一個十分高效的生產環境:java源代碼和模板將被編譯一次,併爲所有的用戶進行緩存。
java源代碼將在運行時進行編譯和加載。當應用程序在運行時,如果一個Java源文件被修改了,那麼這個源文件將會在JVM裏被重新編譯並進行熱交換。
如果有編譯錯誤發生,精確的錯誤發生點將會顯示在瀏覽器裏(僅限DEV模式)。
模板文件也是熱編譯、熱加載的。
連接到java調試器
當在DEV模式運行應用程序時,你可以通過8000端口連接到一個java調試器。
比如,使用NetBeans調試器:
類增強Enhancement
Play plug-in (比如play.PlayPlugin的子類) 可以包含‘enhancers’,以便於在運行時修改應用程序庫,以增加功能。這就是play一些神奇的地方。
內建的play.CorePlugin使用enhancers(play.classloading.enhancers包)來動態添加代碼到你的應用程序裏:
- ContinuationEnhancer –爲控制器類添加continuations支持
- ControllersEnhancer – 讓控制器的action方法實現線程安全,還可以爲方法調用添加HTTP跳轉功能
- LocalvariablesNamesEnhancer – 跟蹤控制器裏的本地變量名稱
- MailerEnhancer – 設置play.mvc.Mailer子類
- PropertiesEnhancer - 所有的應用程序類轉換到可用的JavaBeans(其中的屬性是基於域的)
- SigEnhancer – 爲每個類的簽名計算一個唯一的哈希值,以便自動加載
另外,play.db.jpa.JPAPlugin增強了play.db.jpa.JPABase的子類,提供了更方便的jpa查詢方法。這個一般用於play.db.jpa.Model的子類,作爲應用程序的model類。如果這些類作爲play.db.jpa.GenericModel的子類,會存在一定問題。
要想添加自己的java增強特性,use a subclass of play.classloading.enhancers.Enhancerin your plug-in’s enhance(ApplicationClass) method。