閱讀1007 返回首頁    go 技術社區[雲棲]


《Groovy官方教程》Grape依賴管理器

1 快速入門

1.1添加一個依賴

Grape是一個內嵌在Groovy裏的Jar包依賴管理器。Grape讓你可以快速添加maven倉庫依賴到你的classpath裏,使腳本運行更加簡單。最簡單的一種用法是隻需要在你的腳本裏添加一個注解:

1 @Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')
2 import org.springframework.jdbc.core.JdbcTemplate

@Grab也支持簡潔版:

1 @Grab('org.springframework:spring-orm:3.2.5.RELEASE')
2 import org.springframework.jdbc.core.JdbcTemplate

注意,這裏我們用到了import,這是推薦的做法。當然你也可以在mvnrepository.com搜索到依賴包然後使用@Grab注解形式加到pom.xml實體裏。

1.2特定的倉庫

不是所有的依賴都在maven中心倉庫裏,你可以像下麵這樣添加新的倉庫:

1 @GrabResolver(name='restlet', root='https://maven.restlet.org/')
2 @Grab(group='org.restlet', module='org.restlet', version='1.1.6')

1.3Maven分類器

有些maven依賴需要分類器才能解析,你可以這樣處理:

1 @Grab(group='net.sf.json-lib', module='json-lib', version='2.2.3', classifier='jdk15')

1.4去除過渡依賴

有時你用到了一些過渡版本的依賴,它們可能和正式穩點版本有一點點差別,這時你想要將過渡依賴排除掉,你可以這樣寫:

1 @Grab('net.sourceforge.htmlunit:htmlunit:2.8')
2 @GrabExclude('xml-apis:xml-apis')

(譯者注:原文標題是Excluding Transitive Dependencies,譯者翻譯為過渡依賴。譯者理解為那些非穩定版本的依賴,如果讀者有更好的理解或翻譯請留言,謝謝)

1.5JDBC驅動

你可能需要加載JDBC驅動,因此你需要將JDBC驅動依賴添加到係統類加載器中,示例如下:

1 @GrabConfig(systemClassLoader=true)
2 @Grab(group='mysql', module='mysql-connector-java', version='5.1.6')

1.6從Groovy Shell中使用Grape

通過groovysh使用grape需要調用一個變量:

1 groovy.grape.Grape.grab(group:'org.springframework', module:'spring', version:'2.5.6')

1.7代理設置

如果因為防火牆,你可能需要一個代理服務器才能使用Groovy/Grape,你可以將代理服務器設置通過http.proxyHost和http.proxyPort係統屬性在命令行來設置:

1 groovy -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080 yourscript.groovy

或者你也可以將其添加到JAVA_OPTS環境變量裏:

1 JAVA_OPTS = -Dhttp.proxyHost=yourproxy -Dhttp.proxyPort=8080

1.8日誌

如果你想查看Grape的運行時狀態,可以通過設置係統屬性groovy.grape.report.downloads為true(比如說將-Dgroovy.grape.report.downloads=true添加JAVA_OPTS或調用它),Grape將會打印下麵的一些係統信息:

  • 開始解析依賴
  • 開始下載工件(原文為artifact,工件的意思)
  • 重新下載工件
  • 現在工件的時間和大小

如果要更加詳細的日誌,可以通過提高日誌級別(默認為-1),示例如下:

1 -Divy.message.logger.level=4

2 詳細

Grape(The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine))是Groovy裏內嵌的一個基礎組件,通過grab()方法調用,一些類可以使用Ivy來打包成倉庫給Groovy用。這就支持開發者通過寫一段腳本來實現一些核心庫的需求。裝載這段腳本,Grape將會在運行時下載並鏈接所有依賴的庫。即便這些庫存在於Jcenter,Ibiblio和java.net

Grape遵從Ivy對模塊版本標識和命名轉換。

  • group – 模塊屬於一個模塊組。對應Maven的groupId或者一個Ivy組織。任何匹配/groovy[x][\..*]^/的組都是被保留的,對於Groovy是有特定意義的。
  • module – 加載的模塊名字,對應Mavne的artifactId或Ivy的artifact
  • version – 模塊使用的版本號,要麼是字符串 ‘1.1-RC3’,要麼是Ivy的[2.2.1,)代表2.2.1或更高版本
  • classifier – 可選的分類器,比如jdk15

3 用法

3.1 注解

可以在任何可以放注解的地方放一個或多個groovy.lang.Grab注解來告訴編譯器這段代碼依賴於特定的類庫。這個和添加類庫到Groovy編譯器的效果是一樣的。這個注解將會在任何其他類腳本的運行前被執行,也就是說類的導入可以通過添加@Grab注解來實現:

1 import com.jidesoft.swing.JideSplitButton
2 @Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)')
3 public class TestClassAnnotation {
4     public static String testMethod () {
5         return JideSplitButton.class.name
6     }
7 }

一個合適的grab(…)調用將會加在包含這個注解類的靜態初始化函數上(或者腳本元素)

3.2 多個Grape注解

如果需要在同一個節點使用一個注解多次可以使用@Grapes注解,比如說:

1 @Grapes([
2    @Grab(group='commons-primitives', module='commons-primitives', version='1.0'),
3    @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')])
4 class Example {
5 // ...
6 }

如果不這樣用的話,將會報這樣的錯:

1 Cannot specify duplicate annotation on the same member

3.3 方法調用

一般地grab調用會在一個類或腳本初始化的時候進行。這可以確保groovy代碼依賴的庫在運行時都被類加載器加載進去。一種典型的調用如下:

1 import groovy.grape.Grape
2 // random maven library
3 Grape.grab(group:'com.jidesoft', module:'jide-oss', version:'[2.2.0,)')
4 Grape.grab([group:'org.apache.ivy', module:'ivy', version:'2.0.0-beta1', conf:['default''optional']],
5      [group:'org.apache.ant', module:'ant', version:'1.7.0'])
  • 在同一個地方使用相同的參數多次調用grab是等價的,但是如果使用不同的類加載器可能需要重新運行
  • 如果參數列表傳到grab調用有一個noExceptions參數,那麼將不會拋出參數
  • grab需要一個rootLoader或GroovyClassLoader,也可以是調用類的類加載器鏈。默認情況下列的情形將會失敗並且拋出異常
  • 通過classLoader傳遞的類加載器:參數和它的父類加載器
  • 對象的加載器作為引用對象傳入,參數和它的父類加載器
  • 類的類加載器調用grab

3.3.1 grab(HashMap)參數

  • group: – – 模塊所屬的模塊組,對應Maven的groupId,任何匹配/groovy(|\..|x|x\..)/的組都是保留的,在Groovy模塊中有特殊用途
  • module:– 要加載的模塊名,對應Maven的artifactId
  • version:-也有可能是-使用的模塊版本號,要麼是字符串1.1-RC3要麼是Ivy Range [2.2.1,)表示2.2.1版本或更高版本
  • classifier:–Maven解析的分類器
  • conf:-,默認default’ – The configuration or scope of the module to download. The default conf is `default:映射到maven的runtime和master範圍
  • force-默認是true,用於衝突時的修複,依賴於衝突管理器
  • changing:-,默認是false,是否工件可以修改而不管版本的改變
  • transitive:-,默認是true,是否解析其他依賴

grab有兩個基本變量,一個單個的map一個是帶一個map和多個依賴的map。調用單個map的grab和將一個相同的map傳入兩次調用是一樣的,因此grab參數和依賴可以混合在一個map裏,grab可以當成一個具有命名好參數的方法調用。
下麵的參數每組都是相同的意思,如果傳入多餘一個將是一個運行時錯誤

  • group:, groupId:, organisation:, organization:, org:
  • module:, artifactId:, artifact:
  • version:, revision:, rev:
  • conf:, scope:, configuration:

3.3.2 參數列表

  • classLoader: – 或-解析jar包的類加載器
  • refObject:–最近的父類加載器,可以作為加載器參數被傳遞
  • validate:-,默認是false,是否驗證poms或ivy文件,或者是否直接信任緩存信息(默認false)
  • noExceptions:-,默認是false,如果類加載器或參考查詢失敗,是否應該拋出異常或吞並異常(默認情況)

3.4 命令行工具

Grape增加了一個命令行來執行grape,可以用來檢視和管理本地grape緩存。

1 grape install <groupId> <artifactId> [<version>]

這條命令會安裝特定的groovy模塊或maven工件,如果指定了版本,那麼將安裝特定的的版本,否則安裝最新的版本(類似我們傳遞 * 參數)

1 grape list

列出本地安裝的模塊(如果是groovy模塊,會顯示完整的maven名字)和版本

1 grape resolve (<groupId> <artifactId> <version>)+

返回安裝的模塊或工件的文件位置,並且會返回傳遞依賴模塊的位置。你可以傳入可選參數-ant,-dos,-shell中來得到ant腳本,windows批處理或unix shell腳本格式文件,-ivy將會得到類ivy格式的依賴

3.5 高級配置

3.5.1 倉庫目錄

如果你需要改變下載庫的grape目錄,可以使用grape.root係統屬性來改變默認值(默認值是~/.groovy/grape)

1 groovy -Dgrape.root=/repo/grape yourscript.groovy

3.5.2 自定義Ivy設置

你可以自定義ivy的是指,通過創建一個~/.groovy/grapeConfig.xml文件,如果沒有這個文件,Grape會使用默認配置,詳細參考這裏。需要查找更多關於自定義設置的文檔,可以參考Ivy文檔

3.6 更多示例

使用Apache Commons集合工具類

01 // create and use a primitive array list
02 import org.apache.commons.collections.primitives.ArrayIntList
03  
04 @Grab(group='commons-primitives', module='commons-primitives', version='1.0')
05 def createEmptyInts() { new ArrayIntList() }
06  
07 def ints = createEmptyInts()
08 ints.add(042)
09 assert ints.size() == 1
10 assert ints.get(0) == 42

使用TagSoup

1 // find the PDF links of the Java specifications
2 @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='1.2.1')
3 def getHtml() {
4     def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser())
5     parser.parse("https://docs.oracle.com/javase/specs/")
6 }
7 html.body.'**'.a.@href.grep(~/.*\.pdf/).eachprintln it }

使用Google集合工具類

1 import com.google.common.collect.HashBiMap
2 @Grab(group='com.google.code.google-collections', module='google-collect', version='snapshot-20080530')
3 def getFruit() { [grape:'purple', lemon:'yellow', orange:'orange'as HashBiMap }
4 assert fruit.lemon == 'yellow'
5 assert fruit.inverse().yellow == 'lemon'

啟動Jetty服務器來運行Groovy模塊

01 @Grapes([
02     @Grab(group='org.eclipse.jetty.aggregate', module='jetty-server', version='8.1.7.v20120910'),
03     @Grab(group='org.eclipse.jetty.aggregate', module='jetty-servlet', version='8.1.7.v20120910'),
04     @Grab(group='javax.servlet', module='javax.servlet-api', version='3.0.1')])
05  
06 import org.eclipse.jetty.server.Server
07 import org.eclipse.jetty.servlet.*
08 import groovy.servlet.*
09  
10 def runServer(duration) {
11     def server = new Server(8080)
12     def context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
13     context.resourceBase = "."
14     context.addServlet(TemplateServlet, "*.gsp")
15     server.start()
16     sleep duration
17     server.stop()
18 }
19  
20 runServer(10000)

第一次啟動這個腳本的時候Grape會下載Jetty和它的依賴,並且會緩存它們。我們在8080端口創建了一個Jetty服務,並且將Groovy的TemplateServlet最為根服務。Groovy有自己強大的模板引擎機製。我們啟動這個服務並且運行一段時間。每次有人訪問https://localhost:8080/somepage.gsp的時候,它會顯示somepage.gsp給用戶,這些模板頁是放在一個相同的目錄下座位服務器腳本。

最後更新:2017-05-22 10:03:42

  上一篇:go  《Redis官方文檔》翻譯邀請
  下一篇:go  《Redis官方教程》-Redis的配置