kotlin官方文档: https://kotlinlang.org/docs/maven.html
A. 项目结构:
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
| Demo ├── demo-client │ ├── src │ ├── pom.xml ├── demo-application │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ └── kotlin ├── demo-domain │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ └── kotlin ├── demo-external │ ├── src │ ├── pom.xml ├── demo-infrastructure │ ├── pom.xml │ ├── src ├── demo-start │ ├── src │ ├── pom.xml ├── pom.xml
|
这是一个包含多个子模块的maven
项目。我这里目前只在demo-application
和demo-domain
中同时使用了kotlin
和java
,不过已经足够证明混合编程的可能性。
B. 目前项目使用的java
版本为1.8
,kotlin
版本为1.6.10
,其中项目最外层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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
<name>Demo</name> <groupId>com.leuncle.demo</groupId> <artifactId>Demo-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging>
<properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <org.mapstruct.version>1.4.2.Final</org.mapstruct.version> <spring-boot.version>2.1.3.RELEASE</spring-boot.version> <kotlin.version>1.6.10</kotlin.version> <kotlin.code.style>official</kotlin.code.style> <kotlin.compiler.apiVersion>1.6</kotlin.compiler.apiVersion> </properties>
<modules> <module>demo-start</module> <module>demo-client</module> <module>demo-external</module> <module>demo-application</module> <module>demo-domain</module> <module>demo-infrastructure</module> </modules>
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-bom</artifactId> <version>2.16.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-client</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-external</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-application</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-domain</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-infrastructure</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-reflect</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk7</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-common</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> <version>2.9.8</version> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <configuration> <args> <arg>-Xjsr305=strict</arg> </args> <compilerPlugins> <plugin>lombok</plugin> <plugin>spring</plugin> <plugin>all-open</plugin> </compilerPlugins> <jvmTarget>1.8</jvmTarget> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-lombok</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-noarg</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/main/kotlin</sourceDir> <sourceDir>src/main/java</sourceDir> </sourceDirs> </configuration> </execution> <execution> <id>test-compile</id> <goals> <goal>test-compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/test/kotlin</sourceDir> <sourceDir>src/test/java</sourceDir> </sourceDirs> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.2.0</version> </path> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.4.2.Final</version> </path> </annotationProcessorPaths> </configuration> <executions> <execution> <id>default-compile</id> <phase>none</phase> </execution> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>java-test-compile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>${plugin.source.version}</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build>
|
上面的内容中值得注意的主要是build
部分,pluginManagement
主要用于定义各种插件的配置信息,并不会实际引入,需要在各个子模块中按需引入,子模块中只需要声明groupId
和artifactId
即可。
kotlin-maven-lombok
:处理kotlin
代码转换与lombok
注解处理的先后关系,没有它,如果在同一个模块中,kotlin
代码里面用到了java
代码中的类,而该类使用了lombok
注解,那就会有问题。
allopen
:kotlin
中所有的类默认都是不可继承,spring
框架的代理就不好使了。所以kotlin
代码里会满满的open
。这个插件可以省掉这些open
,为指定注解注解的类在编译时添加open
。以上面的配置为例,可以在compilerPlugins
和jvmTarget
之间加上下面的配置,即可让被Entity
注解所注解的类默认open
。
1 2 3
| <pluginOptions> <option>all-open:annotation=javax.persistence.Entity</option> </pluginOptions>
|
spring
:这个其实就是已经指定一些spring常用注解来添加open。本质上也是依赖allopen
插件的。该插件指定了以下注解: @Component
、 @Async
、 @Transactional
、 @Cacheable
以及 @SpringBootTest
。由于元注解的支持,标注有 @Configuration
、 @Controller
、 @RestController
、 @Service
或者 @Repository
的类会自动打开,因为这些注解标注有元注解@Component
。
no-arg
:该插件为具有特定注解的类生成一个额外的零参数构造函数。这个生成的构造函数是合成的,因此不能从 java
或kotlin
中直接调用,但可以使用反射调用。这允许Java Persistence API(JPA)
实例化一个类,就算它从 kotlin
或 java
的角度看没有无参构造函数。
maven
打包成功,但是本地直接点击IDEA
的Debug/Run
还是报错,类似于:
Lombok requires enabled annotation processing: Do you want to enable annotation processors?
依次点击setting
–> Build
,Execution
,Deployment
–>Annotation Processors
打开编辑页面,勾上Enable annotation processing
前面的勾,保存后需要重启IDEA
C. 子模块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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.leuncle.demo</groupId> <artifactId>Demo-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
<artifactId>demo-domain</artifactId> <packaging>jar</packaging> <name>demo-domain</name>
<dependencies> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-infrastructure</artifactId> </dependency> <dependency> <groupId>com.leuncle.demo</groupId> <artifactId>demo-external</artifactId> </dependency>
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> </dependency>
<dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-reflect</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk7</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-common</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> </plugins> </build> </project>
|
每个子模块需要单独引入kotlin的依赖。