Edit Page

All-open 编译器插件

最终更新: 2024/03/21

Kotlin 的类和成员默认都是 final 的, 但有些框架和库, 比如 Spring AOP, 需要类是 open 的, 因此造成一些不便. all-open 编译器插件会调整 Kotlin 类, 以这些框架的需求, 它会将标记了特定注解的类及其成员变为 open , 而不需要在代码中明确标记 open 关键字.

比如, 当你使用 Spring 时, 你不需要所有的类都变为 open, 只需要标注了特定注解的类, 比如 @Configuration@Service. all-open 插件允许你指定这样的注解.

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

对于 Spring, 你可以使用 kotlin-spring 编译器插件.

Gradle

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

plugins {
    kotlin("plugin.allopen") version "1.9.23"
}
plugins {
    id "org.jetbrains.kotlin.plugin.allopen" version "1.9.23"
}

然后指定需要将类变为 open 的注解:

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

如果类 (或它的任何超类) 标注了 com.my.Annotation 注解, 那么类本身和它的成员都会变为 open.

对元注解(meta-annotation)同样有效:

@com.my.Annotation
annotation class MyFrameworkAnnotation

@MyFrameworkAnnotation
class MyClass // all-open 插件也会将这个类变为 open

MyFrameworkAnnotation 标注了 all-open 元注解 com.my.Annotation, 因此它也成为一个 all-open 注解.

Maven

在你的 pom.xml 文件中添加插件:

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>1.9.23</version>

    <configuration>
        <compilerPlugins>
            <!-- 或者使用 "spring", 支持 Spring -->
            <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>1.9.23</version>
        </dependency>
    </dependencies>
</plugin>

关于 all-open 注解的工作方式, 详情请参见 Gradle 小节.

Spring 支持

如果你使用 Spring, 你可以启用 kotlin-spring 编译器插件, 而不必手动指定 Spring 注解. kotlin-spring 是对 all-open 的一个上层封装, 它的工作方式完全相同.

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

plugins {
    id("org.jetbrains.kotlin.plugin.spring") version "1.9.23"
}
plugins {
    id "org.jetbrains.kotlin.plugin.spring" version "1.9.23"
}

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

<compilerPlugins>
    <plugin>spring</plugin>
</compilerPlugins>

<dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-maven-allopen</artifactId>
        <version>1.9.23</version>
    </dependency>
</dependencies>

这个插件指定了以下注解:

得益于元注解功能, 由注解 @Configuration, @Controller, @RestController, @Service@Repository 标注的类, 都会自动变为 open, 因为这些注解都标注了元注解 @Component.

当然, 你也可以在同一个项目内同时使用 kotlin-allopenkotlin-spring.

如果你使用 start.spring.io 服务生成项目模板, kotlin-spring 插件默认会被启用.

命令行编译器

All-open 编译器插件的 JAR 文件 存在于 Kotlin 编译器的二进制发布包中. 你可以使用 -Xplugin kotlinc 选项指定它的 JAR 文件路径, 来添加这个插件:

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

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

# 插件选项格式是: "-P plugin:<plugin id>:<key>=<value>". 
# 选项可以重复.

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

all-open 插件可以使用的预设置是: spring, micronaut, 和 quarkus.