【gradle源码系列1】 Java DependencyHandler用法示例源码详解

【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&lt;Parameters&gt; {
     *     interface Parameters extends TransformParameters {
     *         {@literal @}Input
     *         Property&lt;String&gt; 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());
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值