12.2.2 All-open 编译器插件

原文链接: https://kotlinlang.org/docs/all-open-plugin.html

12.2.2 All-open 编译器插件

Kotlin 中的类及其成员默认是 final 的,这使得使用 Spring AOP 等要求类为 open 的框架和库时不太方便。all-open 编译器插件让 Kotlin 适应这些框架的要求:使带有特定注解的类及其成员无需显式写出 open 关键字就是开放的。

例如,使用 Spring 时,你不需要让所有类都是开放的,只需要让带有 @Configuration 或 @Service 等特定注解的类开放即可。all-open 插件允许你指定这类注解。

Kotlin 为 Gradle 和 Maven 都提供了 all-open 插件支持,并带有完整的 IDE 集成。

注意: 对于 Spring,你可以使用 kotlin-spring 编译器插件。

Gradle

在 build.gradle(.kts) 文件中添加该插件:

Kotlin

1
2
3
plugins {
    kotlin("plugin.allopen") version "2.4.20"
}

Groovy

1
2
3
plugins {
    id "org.jetbrains.kotlin.plugin.allopen" version "2.4.20"
}

然后指定会让类变为开放的注解列表:

Kotlin

1
2
3
4
allOpen {
    annotation("com.my.Annotation")
    // annotations("com.another.Annotation", "com.third.Annotation")
}

Groovy

1
2
3
4
allOpen {
    annotation("com.my.Annotation")
    // annotations("com.another.Annotation", "com.third.Annotation")
}

如果某个类(或它的任何父类)带有 com.my.Annotation 注解,那么这个类本身及其所有成员都会变为开放。

它同样适用于元注解:

1
2
3
4
5
@com.my.Annotation
annotation class MyFrameworkAnnotation

@MyFrameworkAnnotation
class MyClass // 会变成 all-open

MyFrameworkAnnotation 带有 all-open 元注解 com.my.Annotation,因此它也会成为一个 all-open 注解。

Maven

在 pom.xml 文件中添加该插件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>${kotlin.version}</version>

    <configuration>
        <compilerPlugins>

            <plugin>all-open</plugin>
        </compilerPlugins>

        <pluginOptions>

            <option>all-open:annotation=com.my.Annotation</option>
            <option>all-open:annotation=com.their.AnotherAnnotation</option>
        </pluginOptions>
    </configuration>

    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-allopen</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
    </dependencies>
</plugin>

关于 all-open 注解如何工作的详细信息,请参阅 Gradle 一节。

Spring 支持

如果你使用 Spring,可以启用 kotlin-spring 编译器插件,而不必手动指定 Spring 注解。kotlin-spring 是构建在 all-open 之上的包装,其行为与它完全一致。

在 build.gradle(.kts) 文件中添加 spring 插件:

Kotlin

1
2
3
plugins {
    id("org.jetbrains.kotlin.plugin.spring") version "2.4.20"
}

Groovy

1
2
3
plugins {
    id "org.jetbrains.kotlin.plugin.spring" version "2.4.20"
}

在 Maven 中,spring 插件由 kotlin-maven-allopen 插件依赖提供,因此要在 pom.xml 文件中启用它:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<compilerPlugins>
    <plugin>spring</plugin>
</compilerPlugins>

<dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-maven-allopen</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
</dependencies>

该插件指定了以下注解:

得益于对元注解的支持,带有 @Configuration、@Controller、@RestController、@Service 或 @Repository 注解的类会自动变为开放,因为这些注解本身就带有 @Component 元注解。

当然,你可以在同一个项目中同时使用 kotlin-allopen 和 kotlin-spring。

注意: 如果你通过 start.spring.io 服务生成项目模板,kotlin-spring 插件会默认启用。

命令行编译器

All-open 编译器插件的 JAR 包含在 Kotlin 编译器的二进制发行版中。你可以通过 -Xplugin kotlinc 选项提供其 JAR 文件的路径来挂载该插件:

1
-Xplugin=$KOTLIN_HOME/lib/allopen-compiler-plugin.jar

你可以使用 annotation 插件选项直接指定 all-open 注解,或者启用_预设_:

1
2
3
4
5
# The plugin option format is: "-P plugin:<plugin id>:<key>=<value>".
# Options can be repeated.

-P plugin:org.jetbrains.kotlin.allopen:annotation=com.my.Annotation
-P plugin:org.jetbrains.kotlin.allopen:preset=spring

可用于 all-open 插件的预设包括:spring、micronaut 和 quarkus。