一直以來,Java/Spring開發被認為是笨重的代表,無法快速生成項目原型和骨架。所以,Spring推出了Spring Roo這個項目,幫助我們快速生成項目原型。本文參考自Spring Roo的官方文檔,如果熟悉英文的話可以直接看原文檔,內容更加豐富。
安裝
安裝命令行工具
Spring Roo是一套命令行工具,如果你使用的是Eclipse/STS,還可以使用Eclipse對應的插件。
首先先來下載命令行工具。到下載頁面,選擇對應版本下載。這里我選擇的是最新的2.0.0.RC1 ,畢竟我有更新強迫癥。下載完成之后解壓,會得到一個文件夾,其中bin
目錄下就是Spring Roo的可執行文件了。可以看到它有bat
和sh
兩種格式,可以在不同系統上運行。為了方便以后在終端窗口運行,我建議同時將這個文件夾添加到環境變量中。
安裝好之后,打開命令提示符或者其他終端窗口,輸入roo
命令,就可以啟動Roo了。值得提一點,Roo會在命令提示符對應的文件夾位置創建項目,所以如果需要在特定位置創建項目,先在命令提示符中切換到該文件夾,然后再啟動Roo。

安裝Eclipse插件
打開你的Eclipse/STS,然后遵循以下步驟:
- 點擊菜單欄 Help ? Install New Software
- 點擊 Available Software sites
- 點擊 Import 按鈕
- 找到 "$ROO_HOME/conf/sts-sites-bookmarks.xml" 并確定,這里
$ROO_HOME
是你安裝Roo的目錄 - 根據需要選擇對應的版本
- 在過濾欄輸入
roo
- 選中功能 Spring IDE Roo Support
- 然后一路確定并允許條款
- 最后重啟IDE即可
下面是官方文檔的圖,如果有疑問照著這張圖來就行了。

到這一步還沒完,插件是安裝好了,但是還沒有配置。其實要配置的也很簡單,告訴插件你的Roo工具安裝到哪里就行了。點擊 Window ? Preferences ? Spring ? Roo Support ,打開設置,然后照著官方文檔截圖設置好你的工具路徑即可。

這樣插件就設置完畢了。其實這個插件也沒啥作用,就是在Eclipse中開了一個窗口,能運行Roo命令,和直接在命令提示符中運行其實是一樣的。
使用Roo
運行Roo腳本
$ROO_HOME\samples
文件夾下有三個示例項目腳本,使用Roo運行它們可以快速創建相應的項目。如果沒有耐心,可以直接從這里開始。

比如說,我要運行clinic實例項目,就可以輸入以下命令:
roo> script --file clinic.roo
稍等片刻,程序就會創建完畢。

最后創建出的是一個基于Maven的Spring Boot程序。在IDEA下是這么一個樣子。可以看到項目中有一個名字叫log.roo
的日志文件,它記錄了這個Roo腳本執行的內容。另外不知道為什么程序在IDEA下會有一點報錯,不過不影響編譯和運行。

這個PetClinic示例程序使用了Spring Security來保護頁面。我查閱了一下,Spring Boot下Spring Security默認的用戶名是user
,密碼則在程序啟動的時候隨機輸出到控制臺中。最后運行截圖如下,大家可以自己運行和測試一下這個程序。

腳本解釋
下面來解釋一下PetClinic這個程序的Roo腳本,讓我們來看看Roo是如何工作的。這里只做一下簡單解釋,如果需要詳細資料的話可以參考官方文檔的附錄,完整介紹了Roo的各種命令和參數以及用法。
首先是創建項目并指定頂級包名,這樣會創建一個基于Maven的Spring Boot項目。
project setup --topLevelPackage org.springframework.roo.petclinic
然后是指定JPA存儲類型,這里用的是Hibernate,數據庫是存儲在內存的HSQLDB。當然也可以使用其它數據庫,不過相應地需要增加用戶名等其他參數。
jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
然后是幾個枚舉類,將會在實體類中用到,這里的~
指代前面設置的頂級包名。
enum type --class ~.domain.reference.PetType
enum constant --name DOG
enum constant --name CAT
enum constant --name BIRDenum type --class ~.domain.reference.Specialty
enum constant --name CARDIOLOGY
enum constant --name DENTISTRY
enum constant --name NUTRITION
然后是項目中的幾個實體類。
entity jpa --class ~.domain.Pet --sequenceName PET_SEQ --entityFormatExpression "#{name} (#{type})"
entity jpa --class ~.domain.Visit --sequenceName VISIT_SEQ --entityFormatMessage visit_format
entity jpa --class ~.domain.AbstractPerson --abstract
entity jpa --class ~.domain.Vet --extends ~.domain.AbstractPerson --entityFormatExpression "#{lastName} (#{specialty})"
entity jpa --class ~.domain.Owner --extends ~.domain.AbstractPerson --entityFormatExpression "#{lastName} (#{city})"
之后的叫本詳細設置了每個實體類的屬性以及對應關系,由于比較多所以我只挑選了幾個典型的。在設置實體類之前,需要使用focus
命令指定要設置的實體類。
focus --class ~.domain.Pet
field boolean --fieldName sendReminders --notNull --primitive
field string --fieldName name --notNull --sizeMin 1
field number --fieldName weight --type java.lang.Float --notNull --min 0
field enum --fieldName type --type ~.domain.reference.PetType --notNull
field set --fieldName visits --type ~.domain.Visitfocus --class ~.domain.AbstractPerson
field string --fieldName firstName --sizeMin 3 --sizeMax 30
field string --fieldName lastName --notNull --sizeMin 3 --sizeMax 30
field string --fieldName address --notNull --sizeMax 50 --sizeMin 1
field string --fieldName city --notNull --sizeMax 30
field string --fieldName telephone --notNull
field string --fieldName homePage --sizeMax 30
field string --fieldName email --sizeMax 30 --sizeMin 6
field date --fieldName birthDay --type java.util.Date --notNull
然后設置實體類之間的投影關系并設置JPA Repository。
entity projection --class ~.domain.VetInfo --entity ~.domain.Vet --fields id,firstName,lastName,specialty --entityFormatExpression "#{firstName} #{lastName}"
repository jpa --entity ~.domain.Vet --interface ~.repository.VetRepository --defaultReturnType ~.domain.VetInforepository jpa --all --package ~.repository
service --all --apiPackage ~.service.api --implPackage ~.service.impl
然后是設置DTO(數據傳輸對象),它和頁面中的表單等信息對應,然后在后臺轉換為相應的實體類。在這里還可以指定finder,也就是查詢條件,查詢條件的規則請參考Spring Data JPA的相關內容。
dto --class ~.domain.PetNameAndWeightFormBean
field string --fieldName name
field number --fieldName weight --type java.lang.Float
finder add --entity ~.domain.Pet --name findByNameAndWeight --formBean ~.domain.PetNameAndWeightFormBean
然后是設置Spring Web MVC,這里指定Thymeleaf作為視圖層,并為所有控制器生成JSON和Thymeleaf視圖。
web mvc setup
web mvc view setup --type THYMELEAF
web mvc controller --all --responseType JSON
web mvc controller --all --responseType THYMELEAF
然后是生成查詢和詳情頁面。這里針對前面設置的所有查詢條件生成相應的查詢頁面,然后生成指定實體類的詳情頁面。最后指定了頁面語言,目前好像只支持英語和西班牙語。
// Publishing finders
web mvc finder --all --responseType THYMELEAF// Adding details
web mvc detail --entity ~.domain.Owner --field pets --views list,show,findByCityLike --responseType THYMELEAF
web mvc detail --all --views list,show --responseType THYMELEAFweb mvc language --code es
然后使用了Spring Security保護了一下程序。第一行的是使用Spring Security的默認配置,用戶名是user
,密碼是打印在控制臺的隨機字符串。第二行配置了一下用戶權限,只有管理員角色的用戶才能執行刪除操作。
security setup --provider DEFAULTsecurity authorize --class ~.service.impl.OwnerServiceImpl --method delete.* --roles ADMIN
然后啟用了審計功能,程序會自動記錄相應實體類的編輯時間和編輯者。
jpa audit setup
jpa audit add --entity ~.domain.Pet
jpa audit add --entity ~.domain.Owner
jpa audit add --entity ~.domain.Visit
jpa audit add --entity ~.domain.Vet
然后啟用了Web服務端點功能,這些端點可以在/services
URL下查看。
ws endpoint --service ~.service.api.OwnerService --sei ~.ws.api.OwnerWebService --class ~.ws.endpoint.OwnerWebServiceEndpoint --config ~.config.WsEndpointsConfiguration
ws endpoint --service ~.service.api.PetService --sei ~.ws.api.PetWebService --class ~.ws.endpoint.PetWebServiceEndpoint --config ~.config.WsEndpointsConfiguration
最后自動為這些實體類和服務生成單元測試和集成測試。
// Generating unitary tests for all entities
test unit --class ~.domain.Owner
test unit --class ~.domain.Pet
test unit --class ~.domain.Vet
test unit --class ~.domain.Visit// Repository integration tests
test integration --class ~.repository.VetRepository
test integration --class ~.repository.OwnerRepository
test integration --class ~.repository.VisitRepository
test integration --class ~.repository.PetRepository// Controller integration tests
test integration --class ~.web.OwnersCollectionJsonController
test integration --class ~.web.PetsItemJsonController
test integration --class ~.web.VetsCollectionThymeleafController
test integration --class ~.web.VisitsItemThymeleafController