【gradle源码系列1】 java DependencyHandler用法示例源码详解
文章目录
DependencyHandler用于声明依赖关系。依赖关系分组为配置(参见org.gradle.api.artifacts.Configuration)。
语法
要为配置声明特定的依赖关系,可以使用以下语法:
dependencies {
<configurationName> <dependencyNotation>
}
声明依赖关系基本方式:
plugins {
id 'java' // 这样我们就可以在依赖中使用'implementation'和'testImplementation'
}
dependencies {
// 对于在构件库中找到的依赖项,可以使用 group:name:version 标记法
implementation 'commons-lang:commons-lang:2.6'
testImplementation 'org.mockito:mockito:1.9.0-rc1'
// map标记法
implementation group: 'com.google.code.guice', name: 'guice', version: '1.0'
// 声明任意文件作为依赖项
implementation files('hibernate.jar', 'libs/spring.jar')
// 将'libs'目录下的所有jar包放入编译类路径中
implementation fileTree('libs')
}
高级依赖配置
通过传递一个配置闭包,可以在声明依赖关系时进行一些高级配置。
dependencies {
<configurationName>(<dependencyNotation>){
<configStatement1>
<configStatement2>
}
}
示例包括高级依赖声明,包括:
- 在冲突时强制使用特定的依赖版本。
- 根据名称、组或两者来排除特定的依赖项。有关每个依赖项排除的更多详细信息,请参见org.gradle.api.artifacts.ModuleDependency#exclude(java.util.Map)文档。
- 避免对某些依赖项进行传递性依赖。
plugins {
id 'java' // 这样我们就可以声明'implementation'依赖
}
dependencies {
implementation('org.hibernate:hibernate') {
// 在冲突的情况下,使用hibernate 3.1版本
version {
strictly('3.1')
}
// 排除特定的传递性依赖
exclude module: 'cglib' //根据构件名称排除
exclude group: 'org.jmock' //根据组排除
exclude group: 'org.unwanted', module: 'iAmBuggy' //根据名称和组都排除
// 禁用此依赖项的所有传递性依赖项
transitive = false
}
}
更多高级配置示例
当依赖模块具有多个构件时有用:
- 声明对模块的特定配置的依赖关系。
- 显式指定构件。也可以参考org.gradle.api.artifacts.ModuleDependency#artifact(groovy.lang.Closure)。
plugins {
id 'java' // 这样我们就可以声明'implementation'依赖
}
dependencies {
// 配置对模块的特定配置的依赖关系
implementation configuration: 'someConf', group: 'org.someOrg', name: 'someModule', version: '1.0'
// 配置对'someLib'模块的依赖关系
implementation(group: 'org.myorg', name: 'someLib', version:'1.0') {
// 显式添加依赖项构件
artifact {
// 当某些构件属性不规范时很有用
name = 'someArtifact' //构件名称与模块名称不同
extension = 'someExt'
type = 'someType'
classifier = 'someClassifier'
}
}
}
依赖标记法
有几种支持的依赖标记法,如下所述。对于使用此方式声明的每个依赖项,都会创建一个Dependency对象。可以使用此对象查询或进一步配置依赖项。
您还可以直接添加 org.gradle.api.artifacts.Dependency 的实例:
<configurationName> <instance>
依赖项还可以使用提供任何其他支持的依赖标记法的Provider进行声明。
外部依赖项
支持两种方式声明对外部模块的依赖项。
一种是字符串标记法,
格式如下:
<configurationName> "<group>:<name>:<version>:<classifier>@<extension>"
另一种是map标记法:
<configurationName> group: <group>, name: <name>, version: <version>, classifier:
<classifier>, ext: <extension>
在这两种标记法中,除了名称以外的所有属性都是可选的。
外部依赖项由org.gradle.api.artifacts.ExternalModuleDependency表示。
项目依赖项
要添加项目依赖项,使用以下标记法:
<configurationName> project(':some-project')
标记法 project(‘:project-a’) 类似于在多模块gradle项目中配置projectA时使用的语法。
通过将目标配置视为变体,并针对其执行变体感知属性匹配来解析项目依赖项。
但是,为了覆盖此过程,可以指定显式的目标配置:
<configurationName> project(path: ':project-a', configuration: 'someOtherConfiguration')
使用org.gradle.api.artifacts.ProjectDependency表示项目依赖项。
文件依赖项
您还可以使用org.gradle.api.file.FileCollection添加文件依赖项:
<configurationName> files('a file')
文件依赖项由org.gradle.api.artifacts.SelfResolvingDependency表示。
对其他配置的依赖关系
您可以使用org.gradle.api.artifacts.Configuration添加对其他配置的依赖项。
当配置来自与目标配置相同的项目时,目标配置将被更改为扩展所提供的配置。
当配置来自不同的项目时,会添加一个项目依赖项。
Gradle特定发布的依赖项
可以依赖于Gradle API或Gradle附带的库。这在Gradle插件开发中非常有用。示例:
// 我们的Gradle插件是用groovy编写的
plugins {
id 'groovy'
}
// 现在我们可以使用'implementation'配置声明依赖项
dependencies {
// 使用Gradle附带的Groovy版本:
implementation localGroovy()
// 我们的插件需要Gradle API接口和类进行编译:
implementation gradleApi()
// 我们将使用Gradle测试工具包来测试构建逻辑:
testImplementation gradleTestKit()
}
客户端模块依赖项
要向配置中添加客户端模块,可以使用以下标记法:
<configurationName> module(<moduleNotation>) {
<module dependencies>
}
模块标记法与上述依赖标记法相同,只是classifier属性不可用。
客户端模块由org.gradle.api.artifacts.ClientModule表示。
源码详解
/**
* DependencyHandler用于声明依赖关系。依赖关系分组为配置(参见org.gradle.api.artifacts.Configuration)。
*
* 要为配置声明特定的依赖关系,可以使用以下语法:
*
* dependencies {
* <configurationName> <dependencyNotation>
* }
*
* 示例展示了声明依赖关系的基本方式。
*
* plugins {
* id 'java' // 这样我们就可以在依赖中使用'implementation'和'testImplementation'
* }
*
* dependencies {
* // 对于在构件库中找到的依赖项,可以使用 group:name:version 标记法
* implementation 'commons-lang:commons-lang:2.6'
* testImplementation 'org.mockito:mockito:1.9.0-rc1'
*
* // map标记法
* implementation group: 'com.google.code.guice', name: 'guice', version: '1.0'
*
* // 声明任意文件作为依赖项
* implementation files('hibernate.jar', 'libs/spring.jar')
*
* // 将'libs'目录下的所有jar包放入编译类路径中
* implementation fileTree('libs')
* }
*
* 高级依赖配置
* 通过传递一个配置闭包,可以在声明依赖关系时进行一些高级配置。
*
* dependencies {
* <configurationName>(<dependencyNotation>){
* <configStatement1>
* <configStatement2>
* }
* }
*
* 示例包括高级依赖声明,包括:
* - 在冲突时强制使用特定的依赖版本。
* - 根据名称、组或两者来排除特定的依赖项。有关每个依赖项排除的更多详细信息,请参见org.gradle.api.artifacts.ModuleDependency#exclude(java.util.Map)文档。
* - 避免对某些依赖项进行传递性依赖。
*
* plugins {
* id 'java' // 这样我们就可以声明'implementation'依赖
* }
*
* dependencies {
* implementation('org.hibernate:hibernate') {
* // 在冲突的情况下,使用hibernate 3.1版本
* version {
* strictly('3.1')
* }
*
* // 排除特定的传递性依赖
* exclude module: 'cglib' //根据构件名称排除
* exclude group: 'org.jmock' //根据组排除
* exclude group: 'org.unwanted', module: 'iAmBuggy' //根据名称和组都排除
*
* // 禁用此依赖项的所有传递性依赖项
* transitive = false
* }
* }
*
* 更多高级配置示例,当依赖模块具有多个构件时有用:
* - 声明对模块的特定配置的依赖关系。
* - 显式指定构件。也可以参考org.gradle.api.artifacts.ModuleDependency#artifact(groovy.lang.Closure)。
*
* plugins {
* id 'java' // 这样我们就可以声明'implementation'依赖
* }
*
* dependencies {
* // 配置对模块的特定配置的依赖关系
* implementation configuration: 'someConf', group: 'org.someOrg', name: 'someModule', version: '1.0'
*
* // 配置对'someLib'模块的依赖关系
* implementation(group: 'org.myorg', name: 'someLib', version:'1.0') {
* // 显式添加依赖项构件
* artifact {
* // 当某些构件属性不规范时很有用
* name = 'someArtifact' //构件名称与模块名称不同
* extension = 'someExt'
* type = 'someType'
* classifier = 'someClassifier'
* }
* }
* }
*
* 依赖标记法
* 有几种支持的依赖标记法,如下所述。对于使用此方式声明的每个依赖项,都会创建一个Dependency对象。可以使用此对象查询或进一步配置依赖项。
*
* 您还可以直接添加 org.gradle.api.artifacts.Dependency 的实例:
*
* <configurationName> <instance>
*
* 依赖项还可以使用提供任何其他支持的依赖标记法的Provider进行声明。
*
* 外部依赖项
* 支持两种方式声明对外部模块的依赖项。
* 一种是字符串标记法,格式如下:
*
* <configurationName> "<group>:<name>:<version>:<classifier>@<extension>"
*
* 另一种是map标记法:
*
* <configurationName> group: <group>, name: <name>, version: <version>, classifier:
* <classifier>, ext: <extension>
*
* 在这两种标记法中,除了名称以外的所有属性都是可选的。
*
* 外部依赖项由org.gradle.api.artifacts.ExternalModuleDependency表示。
*
* 项目依赖项
* 要添加项目依赖项,使用以下标记法:
*
* <configurationName> project(':some-project')
*
* 标记法 project(':project-a') 类似于在多模块gradle项目中配置projectA时使用的语法。
*
* 通过将目标配置视为变体,并针对其执行变体感知属性匹配来解析项目依赖项。
* 但是,为了覆盖此过程,可以指定显式的目标配置:
*
* <configurationName> project(path: ':project-a', configuration: 'someOtherConfiguration')
*
* 使用org.gradle.api.artifacts.ProjectDependency表示项目依赖项。
*
* 文件依赖项
* 您还可以使用org.gradle.api.file.FileCollection添加文件依赖项:
*
* <configurationName> files('a file')
*
* 文件依赖项由org.gradle.api.artifacts.SelfResolvingDependency表示。
*
* 对其他配置的依赖关系
* 您可以使用org.gradle.api.artifacts.Configuration添加对其他配置的依赖项。
*
* 当配置来自与目标配置相同的项目时,目标配置将被更改为扩展所提供的配置。
*
* 当配置来自不同的项目时,会添加一个项目依赖项。
*
* Gradle特定发布的依赖项
* 可以依赖于Gradle API或Gradle附带的库。这在Gradle插件开发中非常有用。示例:
*
* // 我们的Gradle插件是用groovy编写的
* plugins {
* id 'groovy'
* }
* // 现在我们可以使用'implementation'配置声明依赖项
*
* dependencies {
* // 使用Gradle附带的Groovy版本:
* implementation localGroovy()
*
* // 我们的插件需要Gradle API接口和类进行编译:
* implementation gradleApi()
*
* // 我们将使用Gradle测试工具包来测试构建逻辑:
* testImplementation gradleTestKit()
* }
*
* 客户端模块依赖项
* 要向配置中添加客户端模块,可以使用以下标记法:
*
* <configurationName> module(<moduleNotation>) {
* <module dependencies>
* }
*
* 模块标记法与上述依赖标记法相同,只是classifier属性不可用。
* 客户端模块由org.gradle.api.artifacts.ClientModule表示。
*/
public interface DependencyHandler extends ExtensionAware {
/**
* Creates a dependency on the Gradle test-kit API.
*
* @return The dependency.
* @since 2.6
*/
Dependency gradleTestKit();
/**
* Creates a dependency on the Groovy that is distributed with the current version of Gradle.
*
* @return The dependency.
*/
Dependency localGroovy();
/**
* 返回此项目的依赖约束处理程序。
*
* @return 此项目的依赖约束处理程序。
* @since 4.5
*/
DependencyConstraintHandler getConstraints();
/**
* 配置此项目的依赖约束。
*
* <p>该方法会对此项目的{@link org.gradle.api.artifacts.dsl.DependencyConstraintHandler}执行给定操作。</p>
*
* @param configureAction 用于配置模块元数据的操作。
* @since 4.5
*/
void constraints(Action<? super DependencyConstraintHandler> configureAction);
/**
* 返回此项目的组件元数据处理程序。返回的处理程序可用于添加修改所依赖软件组件的元数据的规则。
*
* @return 此项目的组件元数据处理程序。
* @since 1.8
*/
ComponentMetadataHandler getComponents();
/**
* 配置此项目的组件元数据。
*
* <p>该方法会对此项目的{@link org.gradle.api.artifacts.dsl.ComponentMetadataHandler}执行给定操作。</p>
*
* @param configureAction 用于配置模块元数据的操作。
* @since 1.8
*/
void components(Action<? super ComponentMetadataHandler> configureAction);
/**
* 返回此项目的组件模块元数据处理程序。返回的处理程序可用于添加修改所依赖软件组件的元数据的规则。
*
* @return 此项目的组件模块元数据处理程序。
* @since 2.2
*/
ComponentModuleMetadataHandler getModules();
/**
* 配置此项目的模块元数据。
*
* <p>该方法会对此项目的{@link org.gradle.api.artifacts.dsl.ComponentModuleMetadataHandler}执行给定操作。</p>
*
* @param configureAction 用于配置模块元数据的操作。
* @since 2.2
*/
void modules(Action<? super ComponentModuleMetadataHandler> configureAction);
/**
* 创建一个构件解析查询。
*
* @since 2.0
*/
ArtifactResolutionQuery createArtifactResolutionQuery();
/**
* 配置属性模式。该操作会接收一个 {@link AttributesSchema} 实例。
* @param configureAction 配置操作
* @return 配置好的模式
*
* @since 3.4
*/
AttributesSchema attributesSchema(Action<? super AttributesSchema> configureAction);
/**
* 返回此处理程序的属性模式。
* @return 属性模式
*
* @since 3.4
*/
AttributesSchema getAttributesSchema();
/**
* 返回此处理程序的构件类型定义。
* @since 4.0
*/
ArtifactTypeContainer getArtifactTypes();
/**
* 配置此处理程序的构件类型定义。
* @since 4.0
*/
void artifactTypes(Action<? super ArtifactTypeContainer> configureAction);
/**
* 注册一个构件转换器。
*
* <p>
* 注册操作需要指定 {@code from} 和 {@code to} 属性。
* 还可以通过使用 {@link TransformSpec#parameters(Action)} 来为转换操作提供参数。
* </p>
*
* <p>例如:</p>
*
* <pre class='autoTested'>
* // 您有如下转换操作:
* abstract class MyTransform implements TransformAction<Parameters> {
* interface Parameters extends TransformParameters {
* {@literal @}Input
* Property<String> getStringParameter();
* {@literal @}InputFiles
* ConfigurableFileCollection getInputFiles();
* }
*
* void transform(TransformOutputs outputs) {
* // ...
* }
* }
*
* // 您可以像这样注册操作:
*
* def artifactType = Attribute.of('artifactType', String)
*
* dependencies.registerTransform(MyTransform) {
* from.attribute(artifactType, "jar")
* to.attribute(artifactType, "java-classes-directory")
*
* parameters {
* stringParameter.set("Some string")
* inputFiles.from("my-input-file")
* }
* }
* </pre>
*
* @see TransformAction
* @since 5.3
*/
<T extends TransformParameters> void registerTransform(Class<? extends TransformAction<T>> actionType, Action<? super TransformSpec<T>> registrationAction);
/**
* 声明对平台的依赖项。如果目标坐标表示多个潜在组件,则将选择平台组件,而不是库。
*
* @param notation 平台的坐标
*
* @since 5.0
*/
Dependency platform(Object notation);
/**
* 声明对平台的依赖项。如果目标坐标表示多个潜在组件,则将选择平台组件,而不是库。
*
* @param notation 平台的坐标
* @param configureAction 依赖项配置块
*
* @since 5.0
*/
Dependency platform(Object notation, Action<? super Dependency> configureAction);
/**
* 声明对强制平台的依赖项。如果目标坐标表示多个潜在组件,则将选择平台组件,而不是库。
* 强制平台是一个平台,其直接依赖关系是被强制的,这意味着它们将覆盖图中找到的任何其他版本。
*
* @param notation 平台的坐标
*
* @since 5.0
*/
Dependency enforcedPlatform(Object notation);
/**
* 声明对强制平台的依赖项。如果目标坐标表示多个潜在组件,则将选择平台组件,而不是库。
* 强制平台是一个平台,其直接依赖关系是被强制的,这意味着它们将覆盖图中找到的任何其他版本。
*
* @param notation 平台的坐标
* @param configureAction 依赖项配置块
*
* @since 5.0
*/
Dependency enforcedPlatform(Object notation, Action<? super Dependency> configureAction);
/**
* 声明对组件测试夹具的依赖项。
* @param notation 要使用测试夹具的组件的坐标
*
* @since 5.6
*/
Dependency testFixtures(Object notation);
/**
* 声明对组件测试夹具的依赖项,并允许配置生成的依赖项。
* @param notation 要使用测试夹具的组件的坐标
*
* @since 5.6
*/
Dependency testFixtures(Object notation, Action<? super Dependency> configureAction);
/**
* 允许微调目标依赖项的变体选择。可以使用此方法指定分类器等信息。
*
* @param dependencyProvider 依赖项提供者
* @param variantSpec 变体规范
* @return 指向已配置变体的新依赖项提供者
* @since 6.8
*/
Provider<MinimalExternalModuleDependency> variantOf(Provider<MinimalExternalModuleDependency> dependencyProvider, Action<? super ExternalModuleDependencyVariantSpec> variantSpec);
/**
* 允许微调目标依赖项的变体选择。可以使用此方法指定分类器等信息。
*
* @param dependencyProviderConvertible 返回依赖项提供者的可转换的依赖项提供者
* @param variantSpec 变体规范
* @return 指向已配置变体的新依赖项提供者
* @since 7.3
*/
default Provider<MinimalExternalModuleDependency> variantOf(ProviderConvertible<MinimalExternalModuleDependency> dependencyProviderConvertible,
Action<? super ExternalModuleDependencyVariantSpec> variantSpec) {
return variantOf(dependencyProviderConvertible.asProvider(), variantSpec);
}
/**
* 配置此依赖项提供者以选择目标组件的平台变体
* @param dependencyProvider 依赖项提供者
* @return 指向组件平台变体的新依赖项提供者
* @since 6.8
*/
default Provider<MinimalExternalModuleDependency> platform(Provider<MinimalExternalModuleDependency> dependencyProvider) {
return variantOf(dependencyProvider, ExternalModuleDependencyVariantSpec::platform);
}
/**
* 配置此依赖项提供者以选择目标组件的平台变体
* @param dependencyProviderConvertible 返回依赖项提供者的可转换的依赖项提供者
* @return 指向组件平台变体的新依赖项提供者
* @since 7.3
*/
default Provider<MinimalExternalModuleDependency> platform(ProviderConvertible<MinimalExternalModuleDependency> dependencyProviderConvertible) {
return platform(dependencyProviderConvertible.asProvider());
}
/**
* 配置此依赖项提供者以选择目标组件的强制平台变体
* @param dependencyProvider 依赖项提供者
* @return 指向组件强制平台变体的新依赖项提供者
* @since 7.3
*/
Provider<MinimalExternalModuleDependency> enforcedPlatform(Provider<MinimalExternalModuleDependency> dependencyProvider);
/**
* 配置此依赖项提供者以选择目标组件的强制平台变体
* @param dependencyProviderConvertible 返回依赖项提供者的可转换的依赖项提供者
* @return 指向组件强制平台变体的新依赖项提供者
* @since 7.3
*/
default Provider<MinimalExternalModuleDependency> enforcedPlatform(ProviderConvertible<MinimalExternalModuleDependency> dependencyProviderConvertible) {
return enforcedPlatform(dependencyProviderConvertible.asProvider());
}
/**
* 配置此依赖项提供者以选择目标组件的测试夹具变体
* @param dependencyProvider 依赖项提供者
* @return 指向组件测试夹具变体的新依赖项提供者
* @since 6.8
*/
default Provider<MinimalExternalModuleDependency> testFixtures(Provider<MinimalExternalModuleDependency> dependencyProvider) {
return variantOf(dependencyProvider, ExternalModuleDependencyVariantSpec::testFixtures);
}
/**
* 配置此依赖项提供者以选择目标组件的测试夹具变体
* @param dependencyProviderConvertible 返回依赖项提供者的可转换的依赖项提供者
* @return 指向组件测试夹具变体的新依赖项提供者
* @since 7.3
*/
default Provider<MinimalExternalModuleDependency> testFixtures(ProviderConvertible<MinimalExternalModuleDependency> dependencyProviderConvertible) {
return testFixtures(dependencyProviderConvertible.asProvider());
}
}