(Quick Reference)

3.7.1 配置和依赖 - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: null

3.7.1 配置和依赖

Grails features five dependency resolution configurations (or 'scopes'):
  • build: Dependencies for the build system only
  • compile: Dependencies for the compile step
  • runtime: Dependencies needed at runtime but not for compilation (see above)
  • test: Dependencies needed for testing but not at runtime (see above)
  • provided: Dependencies needed at development time, but not during WAR deployment

Within the dependencies block you can specify a dependency that falls into one of these configurations by calling the equivalent method. For example if your application requires the MySQL driver to function at runtime you can specify that like this:

runtime 'com.mysql:mysql-connector-java:5.1.16'

This uses the string syntax: group:name:version. You can also use a Map-based syntax:

runtime group: 'com.mysql',
        name: 'mysql-connector-java',
        version: '5.1.16'

In Maven terminology, group corresponds to an artifact's groupId and name corresponds to its artifactId.

Multiple dependencies can be specified by passing multiple arguments:

runtime 'com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1'

// Or

runtime( [group:'com.mysql', name:'mysql-connector-java', version:'5.1.16'], [group:'net.sf.ehcache', name:'ehcache', version:'1.6.1'] )

Grails提供了如下5种依赖解析配置(或者是‘范围’):

  • build: 只在系统构建时的依赖
  • compile: 编译阶段时的依赖
  • runtime: 运行阶段的依赖,不包括编译阶段(见上解释)
  • test: 测试阶段的依赖,不包括运行阶段
  • provided: 开发阶段的依赖,不包括WAR部署阶段

dependencies代码块中,你可以通过同等的方法调用方式来指定一个依赖。比如你的应用中需要runtime的MySQL驱动,你可以这样处理:

runtime 'com.mysql:mysql-connector-java:5.1.16'

此处使用了字符串语法,其格式是:group:name:version,你也可以使用Map格式的语法:

runtime group: 'com.mysql',
        name: 'mysql-connector-java',
        version: '5.1.16'

对应于Maven术语,group跟工件(artifact)的groupId相对应,nameartifactId相对应。

多个依赖可以通过多参数方式来处理:

runtime 'com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1'

// Or

runtime( [group:'com.mysql', name:'mysql-connector-java', version:'5.1.16'], [group:'net.sf.ehcache', name:'ehcache', version:'1.6.1'] )

Disabling transitive dependency resolution

By default, Grails will not only get the JARs and plugins that you declare, but it will also get their transitive dependencies. This is usually what you want, but there are occasions where you want a dependency without all its baggage. In such cases, you can disable transitive dependency resolution on a case-by-case basis:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    transitive = false
}

// Or runtime group:'com.mysql', name:'mysql-connector-java', version:'5.1.16', transitive:false

禁用依赖解析的传递性

缺省情况下,Grails不仅仅获取你直接声明的JAR和插件,还包含其间接所依赖的。多数情况下,这正是你所需要的,不过在个别情况下,你并不需要这种传递性的依赖。这时,你可以有针对地禁止传递依赖,比如:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    transitive = false
}

// Or runtime group:'com.mysql', name:'mysql-connector-java', version:'5.1.16', transitive:false

Excluding specific transitive dependencies

A far more common scenario is where you want the transitive dependencies, but some of them cause issues with your own dependencies or are unnecessary. For example, many Apache projects have 'commons-logging' as a transitive dependency, but it shouldn't be included in a Grails project (we use SLF4J). That's where the excludes option comes in:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    excludes "xml-apis", "commons-logging"
}

// Or runtime(group:'com.mysql', name:'mysql-connector-java', version:'5.1.16') { excludes([ group: 'xml-apis', name: 'xml-apis'], [ group: 'org.apache.httpcomponents' ], [ name: 'commons-logging' ])

As you can see, you can either exclude dependencies by their artifact ID (also known as a module name) or any combination of group and artifact IDs (if you use the Map notation). You may also come across exclude as well, but that can only accept a single string or Map:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    exclude "xml-apis"
}

排除特定的依赖

传递依赖对你来说是如此的常用,但也有会跟你自己的依赖冲突或者重复的情况,比如很多的Apache项目都有依赖于'commons-logging',但是它不能被包含于Grails工程(其使用的是SLF4J)。因此就产生了excludes选项,比如:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    excludes "xml-apis", "commons-logging"
}

// Or runtime(group:'com.mysql', name:'mysql-connector-java', version:'5.1.16') { excludes([ group: 'xml-apis', name: 'xml-apis'], [ group: 'org.apache.httpcomponents' ], [ name: 'commons-logging' ])

如你所见,你可以通过工件ID(又名模块名称)或者组名加工件ID的方式来排除特定的依赖。你也可以通过exclude来排除,不过此处只能接收一个字符串或者Map:

runtime('com.mysql:mysql-connector-java:5.1.16',
        'net.sf.ehcache:ehcache:1.6.1') {
    exclude "xml-apis"
}

Using Ivy module configurations

If you use Ivy module configurations and wish to depend on a specific configuration of a module, you can use the dependencyConfiguration method to specify the configuration to use.

provided("my.org:web-service:1.0") {
    dependencyConfiguration "api"
}

If the dependency configuration is not explicitly set, the configuration named "default" will be used (which is also the correct value for dependencies coming from Maven style repositories).

使用Ivy模块配置

如果你是使用Ivy的模块配置,并且希望依赖于某一特定模块,你可以使用dependencyConfiguration方法来指定:

provided("my.org:web-service:1.0") {
    dependencyConfiguration "api"
}

如果依赖配置没有明确指定,那么将被使用名为"default"缺省配置(其也可以兼容来自Maven风格的存储仓库)。

Where are the JARs?

With all these declarative dependencies, you may wonder where all the JARs end up. They have to go somewhere after all. By default Grails puts them into a directory, called the dependency cache, that resides on your local file system at user.home/.grails/ivy-cache. You can change this either via the settings.groovy file:

grails.dependency.cache.dir = "${userHome}/.my-dependency-cache"

or in the dependency DSL:

grails.project.dependency.resolution = {
    …
    cacheDir "target/ivy-cache"
    …
}

The settings.groovy option applies to all projects, so it's the preferred approach.

JAR在哪里?

对于所有声明的依赖,你可能好奇,这些JAR都到哪里去了?它们总要有个地方来保存的。缺省情况下,Grails将它们放到依赖缓存的目录,其位于你本地文件系统中user.home/.grails/ivy-cache。你也可以通过settings.groovy来修改,比如:

grails.dependency.cache.dir = "${userHome}/.my-dependency-cache"

或者使用依赖DSL:

grails.project.dependency.resolution = {
    …
    cacheDir "target/ivy-cache"
    …
}

settings.groovy的选项将应用于所有的工程,因为它是最优先使用的。