Kotlin+SpringBootでマルチプロジェクトを行う方法です。
私の利用方法としては、プレゼンテーションレイヤーとそれ以降のレイヤーを分離しマルチプロジェクトにすることで、例えばWebアプリケーションとイベント操作するアプリケーション(Kafkaなど)で同じドメイン知識を使い回すなどに利用しています。
マルチプロジェクトの作成
今回のディレクトリ構成です。
.(Root)
├── share (共通ライブラリとして利用するプロジェクト)
│ ├── src/main/kotlin
│ │ └── com.example.demo.service
│ │ └── HelloService.kt
│ └── build.gradle
├── web (アプリケーションプロジェクト)
│ ├── src/main
│ │ ├── kotlin
│ │ │ └── com.example.demo
│ │ │ ├── DemoApplication.kt
│ │ │ └── controller
│ │ │ └── HelloController.kt
│ │ └── resources
│ │ └── application.yml
│ └── build.gradle
├── build.gradle
└── setting.gradle
setting.gralde修正
マルチプロジェクトにする場合はsetting.gradleに設定を行います。
includeにサブプロジェクトを指定します。
rootProject.name = 'demo'
include 'web', 'share'
build.gradleの修正
まずはプロジェクトrootのbuild.gradleを修正します。
plugins {
id "org.springframework.boot" version "2.2.6.RELEASE"
id "io.spring.dependency-management" version "1.0.9.RELEASE"
id "org.jetbrains.kotlin.jvm" version "1.3.71"
id "org.jetbrains.kotlin.plugin.spring" version "1.3.71"
}
ext {
springBootVersion = "2.2.6.RELEASE"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'kotlin'
apply plugin: 'org.springframework.boot'
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:$springBootVersion"
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin"
implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude group: "org.junit.vintage", module: "junit-vintage-engine"
}
}
test {
useJUnitPlatform()
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '11'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '11'
}
}
}
webプロジェクト
webプロジェクトはコントローラなどのプレゼンテーションレイヤーとしての役割を想定しています。
build.gradle
webプロジェクトのbuild.gradleです。
KotlinでのmainClassはclass名+Kt
になりますのでご注意ください。
bootJar {
mainClassName = "com.example.demo.DemoApplicationKt"
}
dependencies {
implementation project(":share")
}
コード
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
open class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
package com.example.demo.controller
import com.example.demo.service.HelloService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController("/")
class HelloController(
private val helloService: HelloService
) {
@GetMapping()
fun getHello(): String {
return helloService.say()
}
}
その他application.properties
(yams)はこちらのプロジェクトに配置してください。
今回は特に何も記載していません。
shareプロジェクト
shareプロジェクトはサービスなどのドメイン知識など配置するレイヤーとしての役割を想定しています。
build.gradle
shareプロジェクトでのbuild.gradleでは以下のような設定にしています。
shareプロジェクトはライブラリ的な扱いになり、それ単体で実行可能アプリケーションとはしないため bootJar無効にして、jarを有効にしています。
その他外部のライブラリなどを使いたい場合は、dependenciesに追加します。
bootJar {
enabled = false
}
jar {
enabled = true
}
dependencies {
}
コード
package com.example.demo.service
import org.springframework.stereotype.Service
@Service
class HelloService {
fun say(): String {
return "Hello!"
}
}
buildと実行
ではbuildして実行します。
$ gradle :web:build
Starting a Gradle Daemon (subsequent builds will be faster)
<-------------> 0% CONFIGURING [14s]
BUILD SUCCESSFUL in 1m 28s
7 actionable tasks: 7 executed
$ ls -l web/build/libs/
total 43296
-rw-r--r-- 1 ysaito staff 22167040 5 2 22:31 web.jar
$ java -jar web/build/libs/web.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
--一部省略--
2020-05-02 22:33:08.984 INFO 1825 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms
$ curl localhost:8080/
Hello!