在這一期的 精通 Grails 中,Scott Davis 將向您展示 Grails 插件的精彩世界。嚮應用程序中添加新功能將是一件再簡單不過的事情。您將領略插件是如何具有如此魔力的,您還會在 Blogito 應用程序中使用一個插件來實現強大的搜索功能。
在開始階段,精通 Grails 主要著眼於核心 Grails 功能。對如何將基礎部件組合在一起了解得越多,將其結合起來構建一個完善的產品應用程序就會變得越容易。儘管我前面多次提到過插件,但我均有意迴避了對插件做深入的介紹。現在,該是介紹的時候了。
在接下來的幾篇系列文章中,我將與您一起探索 Grails 插件系統。最早,Grails 平台的構建對可插入性是有所考慮的。正因為有了這個雖小卻十分重要的考慮,我們才能很方便地利用上百個預捆綁的功能塊。
在本文寫作之時,清單 1 所示的 Groovy 腳本已經能夠返回 225 個插件。(有關此腳本如何工作的詳細信息,請參見 “實戰 Groovy:構建和解析 XML”。)
def addr = "http://plugins.grails.org/.plugin-meta/plugins-list.xml" def plugins = new XmlSlurper().parse(addr) def count = 0 plugins.plugin.each{ println it.@name count++ } println "Total number of plugins: ${count}" |
要獲得一個更為友好的列表,可以在命令提示符后鍵入 grails list-plugins 或訪問 Grails Plugins 站點(參見 參考資料)。
何為插件?
老練的 Java™ 開發人員都是一些精明的探尋者和收集者。他們從不夢想著去編寫自已的日誌庫;而是簡單地把 log4j JAR 放入其類路徑。需要一個 XML 解析器嗎?那好,將 Xerces JAR 添加到您的項目中即可。這些可插入的功能塊是面向對象編程的可重用性的一種體現。
Grails 插件可服務於同樣的目的,不過,規模更大。它們可以包括很多 JAR 及 GroovyServer Page (GSP)、控制器、TagLib、服務等。就像 SiteMesh 將兩個 GSP 合併成一個一樣,插件可以將兩個或多個 Grails 應用程序合併成一個。這樣您就可以將更多的精力用於核心業務需求,在需要的時候,從外部資源加入所需的額外功能 — 查詢、認證、備用表示層等。
此外,插件實質上也是外部 資源。雖然 Grails 開發團隊已經編寫了一些有價值的插件,但絕大多數插件仍來自於社區。實際上,Grails 團隊一直致力於在適當的時候將其核心功能整合進插件,這就使得 Grails 自身在每次發布的時候都更小也更為穩定。
那麼如何將其應用到 Blogito — 您在本系列中逐步構建的這個 “小型博客” 應用程序中呢?假設您想添加的下一個功能是本地搜索功能。並且您願意採用一個現有的解決方案而不是從頭構建一個您自已的搜索基礎架構,那麼請往下看。
![]() ![]() |
安裝一個搜索插件
這個搜索插件能為您的應用程序帶來類似 Google 那樣的搜索能力。它使用 Apache Lucene 創建索引,用 Compass 將索引鉤掛到 Grails Object Relational Mapping (GORM)/Hibernate 生命周期(參見 參考資料)。這就意味著每當您創建、更新或刪除一個 domain 類時,Lucene 索引都會相應更新。
要想安裝此插件,請鍵入 grails install-plugin searchable。(下一章節將會深入介紹安裝插件時的技術細節。)
接下來,將這行代碼 — static searchable = true — 添加到 grails-app/domain/Entry.groovy,如清單 2 所示:
class Entry { static searchable = true static constraints = { title() summary(maxSize:1000) filename(blank:true, nullable:true) dateCreated() lastUpdated() } static mapping = { sort "lastUpdated":"desc" } static belongsTo = [author:User] String title String summary String filename Date dateCreated Date lastUpdated } |
請注意:必須要顯式地讓 domain 類變成可搜索的。這意味著您可以繼續將基礎架構數據,比如登錄和密碼,保存在隱藏的 User 類中。(關於可搜索主題的在線文檔提供了有關如何指定哪些類和欄位可被包括到索引中的更多信息;請參見 參考資料。)
有了這一行代碼,就為 Blogito 賦予了 Lucene 和 Compass 的強大功能。鍵入 grails run-app,啟動這個應用程序,然後訪問 http://localhost:9090/blogito/searchable。鍵入一個搜索關鍵詞,比如 grails,看一下搜索結果,如圖 1 所示:
雖然搜索出一些結果,但結果不容易描述。要解決這個問題,可以為 Entry.groovy 添加一個 toString() 方法,如清單 3 所示:
class Entry { static searchable = true //snip String toString(){ "${title} (${lastUpdated})" } } |
再次搜索 grails 。這次的結果的用戶友好性會有所提高,如圖 2 所示:
這個可搜索插件的原始功能已經就緒,現在可以採取下一個步驟了:將它深入地集成到您的應用程序內。
![]() ![]() |
探索這個插件的基礎架構
縱覽 Blogito 的所有目錄,這裡似乎沒有任何新的文件。如果通過 Web 瀏覽器訪問 http://localhost:9090/blogito/searchable,那裡應該會有一個 grails-app/controllers/SearchableController.groovy 文件。但奇怪的是,該文件不在那裡。在 lib 目錄中也應該有一些 Lucene 與 Compass 的 JAR 文件,但它一如您首次鍵入 grails create-app 啟動這個項目時一樣,是空的。實際上,對 Blogito 的惟一更改就是在 application.properties 中加入的這一行新代碼,如清單 4 所示:
#utf-8 #Wed Jun 24 15:41:16 MDT 2009 app.version=0.4 app.servlet.version=2.4 app.grails.version=1.1.1 plugins.searchable=0.5.5 plugins.hibernate=1.1.1 app.name=blogito |
通過 plug-ins.searchable 這一行代碼,可以判斷 Blogito 已經知曉 Searchable 插件的存在。那麼所有這些功能都藏在哪了?要想查明,需返回到第一次安裝此插件時一閃而過的那個屏幕輸出。接下來,我將帶您探個究竟。
當鍵入 grails install-plugin searchable 后,所發生的第一件事情是向 Web 發出一個請求來拉出插件的最新列表,如清單 5 所示:
$ grails install-plugin searchable //snip Reading remote plugin list ... [get] Getting: http://svn.codehaus.org/grails/trunk/grails-plugins/ .plugin-meta/plugins-list.xml [get] To: /Users/sdavis/.grails/1.1.1/plugins-list-core.xml [get] last modified = Mon Jun 22 04:16:31 MDT 2009 Reading remote plugin list ... [get] Getting: http://plugins.grails.org/.plugin-meta/plugins-list.xml [get] To: /Users/sdavis/.grails/1.1.1/plugins-list-default.xml [get] last modified = Wed Jun 24 06:51:24 MDT 2009 |
這兩個列表 — core 和 default — 提供了這些插件的元數據,包括作者、描述和版本號。更重要的是,在這裡,Grails 可以發現實際包含這些插件的 ZIP 文件所對應的 URL。清單 6 顯示了來自於 plugins-list-core.xml 文件的有關 Hibernate 插件的信息:
<plugins revision="9011"> <plugin latest-release="1.1.1" name="hibernate"> <release tag="RELEASE_1_1" type="svn" version="1.1"> <title>Hibernate for Grails</title> <author>Graeme Rocher</author> <authorEmail/> <description>A plugin that provides integration between Grails and Hibernate through GORM</description> <documentation>http://grails.org/doc/$version</documentation> <file>http://svn.codehaus.org/grails/trunk/grails-plugins/ grails-hibernate/tags/RELEASE_1_1/grails-hibernate-1.1.zip </file> </release> <!-- snip --> </plugin> </plugins> |
目前,Hibernate 插件是核心插件文件內所列的惟一一個插件。這個列表包含了必需 插件 — Grails 運行所不能或缺的功能。默認列表包括了來自於社區的可選插件。
[火星人 ] 精通 Grails: 了解插件已經有770次圍觀