Springboot Kotlin关于build.gradle.kts ext{}如何写的问题解决记录

关于build.gradle.kts ext{}如何写的问题解决记录

最近新学习了一下Kotlin,然后做一个Springboot的项目基础脚手架,在创建新项目的时候发现gradle脚本也支持Kotlin了,索性做一个纯粹的,全用Kotlin,我觉得现在入Kotlin已经挺晚的了,没想到还有坑😂
下面先说结论,正忙的老铁一把Ctrl+C就走,记得再回来好评啊

👉Ctrl+C结论部分

父模块allprojects中的ext{}或项目的中的ext{}

ext {
        set("logbackVersion", "1.1.1")
    }

实际上在allprojects中的ext和groovy语言版本的使用方法相同,只是语言不同,需要转换一下

子模块的build.gradle.kts中的ext{}

dependencies {
	//注意ext在dependencies里面
    ext {
        set("logbackVersion", "1.1.1")
    }

    testImplementation("junit:junit:4.12")
    implementation("org.slf4j:slf4j-api:1.7.7")
	// 读取方法${ext.get("logbackVersion"),不熟悉的请复习Kotlin
    implementation("ch.qos.logback:logback-core:${ext.get("logbackVersion")}")
    implementation("ch.qos.logback:logback-classic:${ext.get("logbackVersion")}")
}

★20210824更新,子模块可以使用allprojects中定义的ext,方法如下:

dependencies 
    testImplementation("junit:junit:4.12")
    implementation("org.slf4j:slf4j-api:1.7.7")
	// 不同的是加了一个project
    implementation("ch.qos.logback:logback-core:${project.ext.get("logbackVersion")}")
    implementation("ch.qos.logback:logback-classic:${project.ext.get("logbackVersion")}")
}

原因在于子模块中也有自己的ext对象,ext对象覆盖了allprojects中的变量的作用域,使用子模块的内置对象project就可以获取到project的全局定义

👉父模块allprojects中的ext{}或项目的中的ext{}

关于父模块或项目的的ext{}实际上没有太多可讲的,只是从groovy语言格式换成kotlin即可

  • ext中调用set方法添加需要配置的参数,

有心的同学如果是idea开发,可以Ctrl点set跟过去看看,会发现这个是ExtraPropertiesExtension接口的一个方法void set(String name, @Nullable Object value);

  • 在使用中注意是ext.get(“XXX”),注意括号里使用双引号
    groovy版本:
buildscript {
	ext {
        dependencyManagementPluginVersion = '1.0.4.RELEASE'
        springBootVersion = '2.0.3.RELEASE'
   	}
   	
	 dependencies {
        classpath("io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

Kotlin版本:

buildscript {
	ext {
        set("dependencyManagementPluginVersion", "1.0.4.RELEASE")
        set("springBootVersion", "2.0.3.RELEASE")
   	}
   	
	 dependencies {
        classpath("io.spring.gradle:dependency-management-plugin:${ext.get("dependencyManagementPluginVersion")}")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${ext.get("springBootVersion")}")
    }
}

具体所有Groovy转Kotlin的规则,请见gradle官方指南:
Migrating build logic from Groovy to Kotlin

👉子模块的build.gradle.kts中的ext{}

子模块的ext才真是这篇要讲的重点问题
原springboot脚手架的子模块build.gradle的groovy脚本如下(示例):

group = "com.muchenxinxi"
version = "1.0.0"


ext {
    springfoxVersion = "2.9.2"
    mapstructVersion = "1.3.0.Final"
    lombokVersion = "1.18.12"
}


dependencies {
	// Swagger 自动生成接口文档
    compile "io.springfox:springfox-swagger2:${springfoxVersion}"
    compile "io.springfox:springfox-swagger-ui:${springfoxVersion}"
}

转换成build.gradle.kts如下(示例):

ext {
       set("springfoxVersion", "2.9.2")
       set("mapstructVersion", "1.3.0.Final")
}
dependencies {
	// Swagger 自动生成接口文档
    implementation("io.springfox:springfox-swagger2:${ext.get("springfoxVersion")}")
    implementation("io.springfox:springfox-swagger-ui:${ext.get("springfoxVersion")}")
}

眼看IDEA没有飘红,心想是成了,于是果断点了刷新按钮,应用gradle的变更,结果buid窗口蹦了出来(构建错误):

org.gradle.internal.exceptions.LocationAwareException: Build file 'D:\MyPlayground\KotlinSpringboot\app-service\build.gradle.kts' line: 20
Cannot get property 'springfoxVersion' on extra properties extension as it does not exist
at Program.execute(Unknown Source)
at Program.execute(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.gradle.api.plugins.ExtraPropertiesExtension$UnknownPropertyException: Cannot get property 'springfoxVersion' on extra properties extension as it does not exist
at Build_gradle$2.invoke(build.gradle.kts:20)
at Build_gradle$2.invoke(build.gradle.kts:1)
at Build_gradle.<init>(Unknown Source)

看意思是说没有找到springfoxVersion这个值在extension(ext)中不存在,What?(问号脸)
明明在dependencies上面写了呀,我TM在Groovy都没毛病。。。这。。。
经过从网上一番搜索,有给出以下方案:
1.使用val定义常量,然后在dependencies直接${valName}使用
2.在allprojects中定义
实测,以上两种方式确实可以解决问题,但是想想:val定义常量?总觉得有点别扭;在allprojects中定义?那怎么能行,子模块的内容写到父项目的配置,显然不合理

正苦思冥想,突然发现父项目的build.gradle.kts的allproejct后面有个小标签this: Project
像这样:
allprojects { this: Project
}
这不就是这个对象就是一个变量传给了某个方法的那种提示吗?
Ctrl跟过去是这样的:
ProjectDelegate.kt文件中:

override fun allprojects(action: Action<in Project>) =
        delegate.allprojects(action)

对应的是这个函数
接着再ctrl从dependencies跟了过去:
dependencies{this: DenpendencyHandlerScop
}
发现跳转到了ProjectExtension.kt文件

/**
 * Configures the dependencies for this project.
 *
 * Executes the given configuration block against the [DependencyHandlerScope] for this
 * project.
 *
 * @param configuration the configuration block.
 */
fun Project.dependencies(configuration: DependencyHandlerScope.() -> Unit) =
    DependencyHandlerScope.of(dependencies).configuration()

指向了这个函数,从子模块的dependencies跟过去也是这里
显然DependencyHandlerScope.of()处理父项目和子项目的配置
继续Ctrl跟到DependencyHandlerScope类

/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.kotlin.dsl

import org.gradle.api.Action
import org.gradle.api.Incubating
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.DependencyConstraintHandler
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.kotlin.dsl.support.delegates.DependencyHandlerDelegate


/**
 * Receiver for `dependencies` block providing convenient utilities for configuring dependencies.
 *
 * @see [DependencyHandler]
 */
open class DependencyHandlerScope
private constructor(
    val dependencies: DependencyHandler
) : DependencyHandlerDelegate() {

    companion object {
        fun of(dependencies: DependencyHandler): DependencyHandlerScope =
            DependencyHandlerScope(dependencies)
    }

    override val delegate: DependencyHandler
        get() = dependencies

    @Deprecated(replaceWith = ReplaceWith("constraints"), message = "This method shouldn't be called because the most specific variant should be preferred by the Kotlin compiler", level = DeprecationLevel.HIDDEN)
    override fun constraints(configureAction: Action<in DependencyConstraintHandler>) {
        super.constraints(configureAction)
    }

    /**
     * Configures dependency constraint for this project.
     *
     * @param configureAction the action to use to configure module metadata
     *
     * @since 6.3
     */
    @Incubating
    fun constraints(configureAction: DependencyConstraintHandlerScope.() -> Unit) {
        super.constraints { t -> configureAction(DependencyConstraintHandlerScope.of(t)) }
    }

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependencyNotation notation for the dependency to be added.
     * @return The dependency.
     * @see [DependencyHandler.add]
     */
    operator fun String.invoke(dependencyNotation: Any): Dependency? =
        dependencies.add(this, dependencyNotation)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependencyNotation notation for the dependency to be added.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     * @see [DependencyHandler.add]
     */
    inline operator fun String.invoke(dependencyNotation: String, dependencyConfiguration: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
        dependencies.add(this, dependencyNotation, dependencyConfiguration)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param group the group of the module to be added as a dependency.
     * @param name the name of the module to be added as a dependency.
     * @param version the optional version of the module to be added as a dependency.
     * @param configuration the optional configuration of the module to be added as a dependency.
     * @param classifier the optional classifier of the module artifact to be added as a dependency.
     * @param ext the optional extension of the module artifact to be added as a dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.add]
     */
    operator fun String.invoke(
        group: String,
        name: String,
        version: String? = null,
        configuration: String? = null,
        classifier: String? = null,
        ext: String? = null
    ): ExternalModuleDependency =
        dependencies.create(group, name, version, configuration, classifier, ext).apply { add(this@invoke, this) }

    /**
     * Adds a dependency to the given configuration.
     *
     * @param group the group of the module to be added as a dependency.
     * @param name the name of the module to be added as a dependency.
     * @param version the optional version of the module to be added as a dependency.
     * @param configuration the optional configuration of the module to be added as a dependency.
     * @param classifier the optional classifier of the module artifact to be added as a dependency.
     * @param ext the optional extension of the module artifact to be added as a dependency.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.create]
     * @see [DependencyHandler.add]
     */
    inline operator fun String.invoke(
        group: String,
        name: String,
        version: String? = null,
        configuration: String? = null,
        classifier: String? = null,
        ext: String? = null,
        dependencyConfiguration: ExternalModuleDependency.() -> Unit
    ): ExternalModuleDependency =
        dependencies.add(this, create(group, name, version, configuration, classifier, ext), dependencyConfiguration)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependency dependency to be added.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.add]
     */
    inline operator fun <T : ModuleDependency> String.invoke(dependency: T, dependencyConfiguration: T.() -> Unit): T =
        dependencies.add(this, dependency, dependencyConfiguration)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependencyNotation notation for the dependency to be added.
     * @return The dependency.
     * @see [DependencyHandler.add]
     */
    operator fun Configuration.invoke(dependencyNotation: Any): Dependency? =
        add(name, dependencyNotation)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependencyNotation notation for the dependency to be added.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     * @see [DependencyHandler.add]
     */
    inline operator fun Configuration.invoke(dependencyNotation: String, dependencyConfiguration: ExternalModuleDependency.() -> Unit): ExternalModuleDependency =
        add(name, dependencyNotation, dependencyConfiguration)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param group the group of the module to be added as a dependency.
     * @param name the name of the module to be added as a dependency.
     * @param version the optional version of the module to be added as a dependency.
     * @param configuration the optional configuration of the module to be added as a dependency.
     * @param classifier the optional classifier of the module artifact to be added as a dependency.
     * @param ext the optional extension of the module artifact to be added as a dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.add]
     */
    operator fun Configuration.invoke(
        group: String,
        name: String,
        version: String? = null,
        configuration: String? = null,
        classifier: String? = null,
        ext: String? = null
    ): ExternalModuleDependency =
        create(group, name, version, configuration, classifier, ext).apply { add(this@invoke.name, this) }

    /**
     * Adds a dependency to the given configuration.
     *
     * @param group the group of the module to be added as a dependency.
     * @param name the name of the module to be added as a dependency.
     * @param version the optional version of the module to be added as a dependency.
     * @param configuration the optional configuration of the module to be added as a dependency.
     * @param classifier the optional classifier of the module artifact to be added as a dependency.
     * @param ext the optional extension of the module artifact to be added as a dependency.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.create]
     * @see [DependencyHandler.add]
     */
    inline operator fun Configuration.invoke(
        group: String,
        name: String,
        version: String? = null,
        configuration: String? = null,
        classifier: String? = null,
        ext: String? = null,
        dependencyConfiguration: ExternalModuleDependency.() -> Unit
    ): ExternalModuleDependency =
        add(this.name, create(group, name, version, configuration, classifier, ext), dependencyConfiguration)

    /**
     * Adds a dependency to the given configuration.
     *
     * @param dependency dependency to be added.
     * @param dependencyConfiguration expression to use to configure the dependency.
     * @return The dependency.
     *
     * @see [DependencyHandler.add]
     */
    inline operator fun <T : ModuleDependency> Configuration.invoke(dependency: T, dependencyConfiguration: T.() -> Unit): T =
        add(name, dependency, dependencyConfiguration)

    /**
     * Configures the dependencies.
     */
    inline operator fun invoke(configuration: DependencyHandlerScope.() -> Unit) =
        this.configuration()
}

What?!我看到了ext?再结合DependencyHandlerScope.of(dependencies).configuration()这句代码,得出结论似乎是dependencies中有ext{}
于是乎赶紧把ext{}搬到了dependencies{}里面,经过测试能够正确加载依赖了!Wow~

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值