1. 概述

在 Kotlin 中,默认所有类都是 final 的。这在某些场景下有明显优势,但在与 Spring 集成时却会带来问题。Spring 某些组件(如 AOP、事务管理)要求类不能是 final 的,否则会抛出异常。

解决这个问题的方案有两个:

  • ✅ 手动给需要支持 Spring 功能的类加上 open 关键字
  • ✅ 使用 kotlin-allopen 插件,自动将 Spring 需要的类打开

2. Maven 配置

首先,我们需要在 pom.xml 中引入 kotlin-maven-allopen 插件依赖:

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-allopen</artifactId>
    <version>1.1.4-3</version>
</dependency>

然后,在 kotlin-maven-plugin 中启用插件并指定使用 Spring 预设:

<build>
    <plugins>
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>1.1.4-3</version>
            <configuration>
                <compilerPlugins>
                    <plugin>spring</plugin>
                </compilerPlugins>
                <jvmTarget>1.8</jvmTarget>
            </configuration>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-allopen</artifactId>
                    <version>1.1.4-3</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

⚠️ 注意:版本号要与 Kotlin 编译器版本一致,避免版本冲突。

3. 示例配置类

我们创建一个简单的 Spring 配置类 SimpleConfiguration.kt

@Configuration
class SimpleConfiguration

4. 未使用 kotlin-allopen 插件时的问题

如果不启用 kotlin-allopen 插件,Spring 在加载配置类时会抛出异常:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: 
  Configuration problem: @Configuration class 'SimpleConfiguration' may not be final. 
  Remove the final modifier to continue.

解决方式是手动添加 open 关键字:

@Configuration
open class SimpleConfiguration

但这种方式很繁琐,尤其是类很多的时候。

5. 启用 kotlin-allopen 插件

一旦启用插件,所有被 Spring 注解标记的类(如 @Component, @Service, @Configuration, @RestController 等)都会被自动打开。

反编译查看生成的类,会发现它已经是 open 的:

@Configuration
public open class SimpleConfiguration {
}

这样就无需手动加 open,代码更简洁,也更易维护。

6. 小结

在 Kotlin 与 Spring 整合过程中,由于 Kotlin 默认类是 final 的,会导致 Spring AOP 等功能无法使用。通过引入 kotlin-allopen 插件,可以优雅地解决这个问题,避免手动添加 open,提升开发效率。

源码地址:GitHub(感谢原作者提供示例)

✅ 推荐做法:在所有 Spring Boot + Kotlin 项目中启用 kotlin-allopen 插件
❌ 踩坑提醒:忘记配置插件会导致运行时报错,定位困难,务必在项目初期就配置好


原始标题:Kotlin-allopen and Spring