返回介绍

3 用法

发布于 2025-01-04 00:44:52 字数 7060 浏览 0 评论 0 收藏 0

3.1 注释

可以在任何位置添加一个或多个 groovy.lang.Grab 注释,它们会告诉编译器代码所依赖的某个具体库。这和把库添加到 Groovy 编译器的类路径上的作用是一样的。在脚本中,这种注释会在任何其他类解析之前被发现并执行,所以导入类可以通过 @Grab 正确地得到解析。

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

含有类(或者在注释脚本元素情况下的脚本类)的类静态初始化器会正确地调用 grab(…​)

3.2 多重 Grape 注释

为了在同一节点多次使用 Grape 注释,必须使用 @Grapes ,如下所示:

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

否则,就会出现下列错误:

Cannot specify duplicate annotation on the same member

3.3 方法调用

通常对 grab 的调用往往发生在脚本或类初始化这种早期阶段。这是为了确保在 Groovy 代码依赖库代码前,库可以被类加载器所利用。典型的调用如下所示:

import groovy.grape.Grape
// 随机 maven 库
Grape.grab(group:'com.jidesoft', module:'jide-oss', version:'[2.2.0,)')
Grape.grab([group:'org.apache.ivy', module:'ivy', version:'2.0.0-beta1', conf:['default', 'optional']],
   [group:'org.apache.ant', module:'ant', version:'1.7.0'])
  • 在相同上下文中,参数也相同时,多次对 grab 调用应该是幂等(idempotent)的。但如果同样的代码在不同的 ClassLoader 上下文中调用时,解析就会重新运行。
  • 如果传入 grab 中的 args 映射拥有预定为 true 的 noExceptions 属性,则不会抛出异常。
  • grab 需要在调用类的 ClassLoader 链中指定或存在 grabRootLoader 。默认,如果这样一种 ClassLoader 无法获得,则会反映在模块解析上,就会抛出异常:
    • 通过 classLoader: 参数传入的类加载器,及其父级类加载器;
    • 作为 referenceObject: 参数传入的类加载器,及其父级类加载器;
    • 发出对 grab 调用的类的类加载器。

3.3.1 grab(HashMap) 参数

  • group: -\<字符串型>-模块来自的模块组。直接转换为 Maven groupId。任何匹配 /groovy(|\..|x|x\..)/ 的模块组都被保留下来,可能对 Groovy 支持模块而言有特殊含义。
  • module: -\<字符串型>-要加载的模块名称。直接转换为 Maven artifactId。
  • version: -\<字符串型>,有可能是\-所要使用模块的版本。无论是字面版本 '1.1-RC3' 还是 Ivy 范围 '[2.2.1,]',都表示 2.2.1 或更新的版本。
  • classifier: -\<字符串型>-解析所利用的 Maven 分类器。
  • conf: -\<字符串型>默认为 'default'-意指想要下载的模块的配置或范围,映射至 runtimemaster 范围。
  • force: -\<布尔类型>默认为 true-用于表明该版本必须用在发生冲突的情况下,与冲突管理器无关。
  • changing: -\<布尔类型>默认为 false-是否无需版本名称改变,就能改变工件。
  • transitive: -\<布尔类型>默认为 true-是否解决该模块的其他依赖项。

grab 有两大主要变体,一个带有单一的映射,另一个则带有一个参数映射及多个依赖映射。调用单一映射的 grab 和调用传入两次映射的 grab 完全相同,所以 grab 的参数和依赖项都可以混合在一个单独的映射中,grab 可以作为带有多个已命名参数的单一方法进行调用。

这些参数有以下这些同义词,然而提交多个会造成运行时异常。

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

3.3.2 参数映射的参数

  • classLoader: -\<GroovyClassLaoder> 或 \<RootClassLoader> - 添加要解析的 jar 的类加载器。
  • refObject: -\<Object>-对象类所用的最近的父级类加载器会被作为,尽管传入的是 classLoader
  • validate: -\<布尔类型>默认为 false-是否验证 pom 或 ivy 文件(true),或者相信缓存(false)。
    • noExceptions: -\<布尔类型>默认为 false-如果类加载器解析或仓库查询失败,是否抛出异常(false)或静默失败(true)。

3.4 命令行工具

Grape 添加了一个命令行可执行的 grape ,从而实现对本地 grape 缓存的检查与管理。

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

该命令会安装指定的 Groovy 模块或 Maven 工件。如果指定的是特定的版本,则会安装该版本;如未指定,则安装最新的版本(就好像我们用的是 * )。

grape list

列出本地安装模块(Groovy 模块则要带上它们的完整的 maven 名称)及版本。

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

这将返回 jar 文件的位置,它代表指定模块及相应传递依赖的工件。还可以选择性地传入 -ant-dos-shell ,获取用 ant 脚本、Windows 批处理文件以及 Unix Shell 脚本的格式表达的依赖。也可以传入 -ivy ,查看用类似 ivy 格式表达的依赖。

3.5 高级配置

3.5.1 仓库目录

如果需要改变 grape 用来下载库的目录,可以指定 grape.root 系统属性来改变默认配置(~/.groovy/grape)。

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

3.5.2 自定义 Ivy 设置

可以通过创建一个 ~/.groovy/grapeConfig.xml 文件来自定义 Grape 所使用的 ivy 设置。如果不存在这种文件,可以参考一下 Grape 使用的默认设置

关于自定义设置的详细信息,可参考 Ivy 文档

3.6 更多范例

使用 Apache Commons 集合库:

// 创建并使用原始数组列表  
import org.apache.commons.collections.primitives.ArrayIntList

@Grab(group='commons-primitives', module='commons-primitives', version='1.0')
def createEmptyInts() { new ArrayIntList() }

def ints = createEmptyInts()
ints.add(0, 42)
assert ints.size() == 1
assert ints.get(0) == 42

使用 TagSoup:

// 寻找 Java 规范的 PDF 链接  
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='1.2.1')
def getHtml() {
  def parser = new XmlParser(new org.ccil.cowan.tagsoup.Parser())
  parser.parse("https://docs.oracle.com/javase/specs/")
}
html.body.'**'.a.@href.grep(~/.*\.pdf/).each{ println it }

使用 Google 集合库:

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

启动 Jetty 服务器为 Groovy 模板提供服务:

@Grapes([
  @Grab(group='org.eclipse.jetty.aggregate', module='jetty-server', version='8.1.7.v20120910'),
  @Grab(group='org.eclipse.jetty.aggregate', module='jetty-servlet', version='8.1.7.v20120910'),
  @Grab(group='javax.servlet', module='javax.servlet-api', version='3.0.1')])

import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.*
import groovy.servlet.*

def runServer(duration) {
  def server = new Server(8080)
  def context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
  context.resourceBase = "."
  context.addServlet(TemplateServlet, "*.gsp")
  server.start()
  sleep duration
  server.stop()
}

runServer(10000)

一加载脚本,Grape 就会下载 Jetty 及其依赖,并予以缓存。我们在 8080 端口处创建新的 Jetty 服务器,然后在上下文的根目录暴露 Groovy 的 TemplateServlet —— Groovy 自带一个功能强大的模板引擎机制。启动服务器,让它运行一段时间。每当点击 http://localhost:8080/somepage.gsp 时,就会显示 somepage.gsp 模板。这些模板页面应该和服务器脚本同位于一个目录。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文