Kotlin Compiler Plugins : All-open , Kotlin-spring,No-arg,Kotlin-jpaCompiler Plugins

Compiler Plugins

All-open compiler plugin

Kotlin has classes and their members final by default, which makes it inconvenient to use frameworks and libraries such as Spring AOP that require classes to be open. The all-open compiler plugin adapts Kotlin to the requirements of those frameworks and makes classes annotated with a specific annotation and their members open without the explicit open keyword. For instance, when you use Spring, you don't need all the classes to be open, but only classes annotated with specific annotations like @Configuration or @Service. The all-open plugin allows to specify these annotations.

We provide all-open plugin support both for Gradle and Maven, as well as the IDE integration. For Spring you can use the kotlin-spring compiler plugin (see below).

How to use all-open plugin

Add the plugin in build.gradle:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    }
}

apply plugin: "kotlin-allopen"

Or, if you use the Gradle plugins DSL, add it to the plugins block:

plugins {
  id "org.jetbrains.kotlin.plugin.allopen" version "{{ site.data.releases.latest.version }}"
}

Then specify the annotations that will make the class open:

allOpen {
    annotation("com.my.Annotation")
}

If the class (or any of its superclasses) is annotated with com.my.Annotation, the class itself and all its members will become open.

It also works with meta-annotations:

@com.my.Annotation
annotation class MyFrameworkAnnotation

@MyFrameworkAnnotation
class MyClass // will be all-open

MyFrameworkAnnotation is also the annotation that makes the class open, because it's annotated with com.my.Annotation.

Here's how to use all-open with Maven:

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

    <configuration>
        <compilerPlugins>
            <!-- Or "spring" for the Spring support -->
            <plugin>all-open</plugin>
        </compilerPlugins>

        <pluginOptions>
            <!-- Each annotation is placed on its own line -->
            <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>

Kotlin-spring compiler plugin

You don't need to specify Spring annotations by hand, you can use the kotlin-spring plugin, which automatically configures the all-open plugin according to the requirements of Spring:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    }
}

apply plugin: "kotlin-spring"

Or using the Gradle plugins DSL:

plugins {
  id "org.jetbrains.kotlin.plugin.spring" version "{{ site.data.releases.latest.version }}"
}

The Maven example is similar to the one above.

The plugin specifies the following annotations: @Component, @Async, @Transactional, @Cacheable. Thanks to meta-annotations support classes annotated with @Configuration, @Controller, @RestController, @Service or @Repository are automatically opened since these annotations are meta-annotated with @Component.

Of course, you can use both kotlin-allopen and kotlin-spring in the same project. Note that if you use start.spring.io the kotlin-spring plugin will be enabled by default.

No-arg compiler plugin

The no-arg compiler plugin generates an additional zero-argument constructor for classes with a specific annotation. The generated constructor is synthetic so it can’t be directly called from Java or Kotlin, but it can be called using reflection. This allows the Java Persistence API (JPA) to instantiate the data class although it doesn't have the no-arg constructor from Kotlin or Java point of view (see the description of kotlin-jpa plugin below).

How to use no-arg plugin

The usage is pretty similar to all-open. You add the plugin and specify the list of annotations that must lead to generating a no-arg constructor for the annotated classes.

How to use no-arg in Gradle:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    }
}

apply plugin: "kotlin-noarg"

Or using the Gradle plugins DSL:

plugins {
  id "org.jetbrains.kotlin.plugin.noarg" version "{{ site.data.releases.latest.version }}"
}

Then specify the annotation types:

noArg {
    annotation("com.my.Annotation")
}

Enable invokeInitializers option if you want the plugin to run the initialization logic from the synthetic constructor. Starting from Kotlin 1.1.3-2, it is disabled by default because of KT-18667 and KT-18668 which will be addressed in the future:

noArg {
    invokeInitializers = true
}

How to use no-arg in Maven:

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

    <configuration>
        <compilerPlugins>
            <!-- Or "jpa" for JPA support -->
            <plugin>no-arg</plugin>
        </compilerPlugins>

        <pluginOptions>
            <option>no-arg:annotation=com.my.Annotation</option>
            <!-- Call instance initializers in the synthetic constructor -->
            <!-- <option>no-arg:invokeInitializers=true</option> -->
        </pluginOptions>
    </configuration>

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

Kotlin-jpa compiler plugin

The plugin specifies @Entity and @Embeddable annotations as markers that no-arg constructor should be generated for a class. That's how you add the plugin in Gradle:

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    }
}

apply plugin: "kotlin-jpa"

Or using the Gradle plugins DSL:

plugins {
  id "org.jetbrains.kotlin.plugin.jpa" version "{{ site.data.releases.latest.version }}"
}

The Maven example is similar to the one above.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java系列博客

IDEA中scope 为 provided的问题

2082
来自专栏JAVA技术站

SpringCloud 微服务实现方式 原

消费启动服务,注意EnableFeginClients 一定要加basePackages,要不然扫不到单独作为api的jar包里面接口

1071
来自专栏Netkiller

Spring cloud 之 Feign Client

本文接选自 《Netkiller Java 手札》 12.2.2. Eureka Client 12.2.2.1. Maven <project xmln...

4775
来自专栏一个会写诗的程序员的博客

NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy

This warning, i.e. not an error, message is reported when no SLF4J providers cou...

3481
来自专栏三杯水

CentOS 7.5安装部署Jewel版本Ceph集群

1、修改cpeh.conf文件 注意mon为奇数,如果为偶数,有一个不会安装,另外设置好public_network,并稍微增大mon之间时差允许范围(默认为...

1042
来自专栏osc同步分享

springMVC 表单校验、日期类型的转换

@Controller @RequestMapping("/appointments") public class AppointmentsController...

3127
来自专栏运维

CentOS 7.5安装部署Jewel版本Ceph集群

1、修改cpeh.conf文件 注意mon为奇数,如果为偶数,有一个不会安装,另外设置好public_network,并稍微增大mon之间时差允许范围(默认为0...

1023
来自专栏一个会写诗的程序员的博客

Spring Fu is an incubator for new Spring features about Kotlin and functional bean registration.

Spring Fu is an incubator for new Spring features about Kotlin and functional be...

1364
来自专栏Netkiller

Spring boot with Hessian

节选自《Netkiller Java 手札》一书 5.20. Spring boot with Hessian 5.20.1. Maven <depende...

4038
来自专栏码匠的流水账

聊聊WebClient的LoadBalance支持

spring-cloud-commons-2.0.0.RC1-sources.jar!/org/springframework/cloud/client/loa...

1531

扫码关注云+社区