在Spring MVC和JdbcTemplate
的例子中,為了獲取必要的依賴並添加到Classpath裡,Groovy編譯觸發了Spring Boot CLI。這是錯誤的。但如果需要一個依賴,而沒有失敗代碼來觸發自動依賴解析,又或者所需的依賴CLI不知道,那該怎麼辦?
在閱讀列表應用程序中,我們需要Thymeleaf庫,這樣才能編寫使用了Thymeleaf模板的視圖。我們還需要H2的庫,這樣才能擁有嵌入式的H2數據庫。但因為沒有Groovy代碼會直接引用Thymeleaf或H2的類,所以不會有編譯錯誤來觸發自動依賴解析。因此,我們要幫一幫CLI,在Grabs
類上添加@Grab
依賴。
該把
@Grab
註解放在哪裡? 並不需要像我們這樣,嚴格將@Grab
註解放在一個單獨的類上。它們在ReadingListController
或JdbcReadingListRepository
同樣有效。不過,為了便於組織管理,最好創建一個空類,把所有@Grab
註解放在一起。這樣方便在一個地方看到所有顯式聲明的依賴。
@Grab
註解源自Groovy Grape(Groovy Adaptable Packaging Engine或Groovy Advanced Packaging Engine)工具。從本質上來說,Grape允許Groovy腳本在運行時下載依賴,無需Maven或Gradle這樣的構建工具介入。除了支持@Grab
註解,Spring Boot CLI還用Grape來獲取代碼中推斷出的依賴。
使用@Grab
就和描述依賴一樣簡單。舉例來說,假設你想往項目裡添加H2數據庫,可以往項目的一個Groovy腳本添加如下@Grab
註解:
@Grab(group=\"com.h2database\", module=\"h2\", version=\"1.4.190\")
這樣能明確地聲明依賴的組、模塊和版本號。或者,你也可以用更簡潔的冒號分割表示依賴,這和Gradle構建說明裡的表示方式類似。
@Grab(\"com.h2database:h2:1.4.185\")
這是兩個教科書式的例子,但Spring Boot CLI對@Grab
做了幾處擴展,用起來更簡單。
很多依賴不再要求指定版本號了。可以通過下面的方式,用@Grab
添加H2數據庫依賴:
@Grab(\"com.h2database:h2\")
確切的版本號是由你所使用的CLI的版本來決定的。如果用的是Spring Boot CLI 1.3.0.RELEASE,那麼H2依賴的版本會解析為1.4.190。
這還不算完,很多常用依賴還可以省去Group ID,直接在@Grab
裡寫上模塊的ID。正是這個特性讓上文的@Grab
註解成功加載了H2。
@Grab(\"h2\")
那你該如何獲知某個依賴是需要Group ID和版本號,還是只需要Module ID呢?我在附錄D中提供了一個完整的列表,包含了Spring Boot CLI知道的全部依賴。通常,你可以先試一下只寫Module ID,如果這樣不行,再加上Group ID和版本號。
只用Module ID來表示依賴會很方便,但如果你並不認可Spring Boot選擇的版本號怎麼辦?如果Spring Boot的起步依賴傳遞引入了一個庫的某個版本,但你想要使用修正了bug的新版本又該如何呢?
5.2.1 覆蓋默認依賴版本
Spring Boot引入了新的@GrabMetadata
註解,可以和@Grab
搭配使用,用屬性文件裡的內容來覆蓋默認的依賴版本。
要用@GrabMetadata
,可以把它加到某個Groovy腳本文件裡,提供相應的屬性文件來覆蓋依賴元數據:
@GrabMetadata(\"com.myorg:custom-versions:1.0.0\")
這會從Maven倉庫的com/myorg目錄裡加載一個名為custom-versions.properties的文件。文件裡的每一行都應該有Group ID和Module ID。以這兩個東西為鍵名,屬性則是值。例如,要把H2的默認版本覆蓋為1.4.186,可以把@GrabMetadata
指向一個包含如下內容的屬性文件:
com.h2database:h2=1.4.186
使用Spring IO平台
你可能希望讓
@GrabMetadata
使用Spring IO平台(http://platform.spring.io/platform/)上定義的依賴版本。該平台提供了一套依賴和版本。明確哪個版本的Spring能和其他庫的什麼版本搭配使用。Spring IO平台提供的依賴和版本是Spring Boot已知依賴庫的一個超集,包含了很多Spring應用程序經常用到的第三方庫。如果你想在Spring IO平台上構建Spring Boot CLI應用程序,只需要在Groovy腳本中添加如下
@GrabMetadata
即可。@GrabMetadata(\'io.spring.platform:platform-versions:1.0.4.RELEASE\')
這會覆蓋CLI的默認依賴版本,使Spring IO平台定義的版本取而代之。
你可能會有疑問,Grape又是從哪裡獲取所有這些依賴的呢?這是可配置的嗎?讓我們來看看你該如何管理Grape獲取依賴的倉庫集。
5.2.2 添加依賴倉庫
默認情況下,@Grab
聲明的依賴是從Maven中心倉庫(http://repo1.maven.org/maven2/)拉取的。此外,Spring Boot還註冊了Spring的里程碑及快照倉庫,以便獲取Spring項目的預發佈版本依賴。對很多項目而言,這就足夠了。但要是你的項目需要的庫不在這兩者之中該怎麼辦呢?或者你的工作環境在公司防火牆內,必須使用內部倉庫又該如何?
沒有問題。@GrabResolver
註解可以讓你指定額外的倉庫,用來獲取依賴。
舉個例子,假設你想使用最新的Hibernate,而最新的Hibernate版本只能從JBoss的倉庫裡獲取到。那麼你需要通過@GrabResolver
來添加倉庫:
@GrabResolver(name=\'jboss\', root=
\'https://repository.jboss.org/nexus/content/groups/public-jboss\')
這裡通過name
屬性將該解析器命名為jboss,通過root
屬性來指定倉庫的URL。
你已經瞭解了Spring Boot CLI是如何編譯代碼以及自動按需解析已知依賴庫的。在@Grab
的支持下,CLI可以解析各種它無法自動解析的依賴。基於CLI的應用程序無需Maven或Gradle構建說明文件(傳統方式開發的Java應用程序需要這個文件)。但解析依賴和編譯代碼並不是構建過程的全部,項目的構建通常還要執行自動化測試,要是沒有構建說明文件,又該如何運行測試呢?