LoginSignup
1
2

More than 3 years have passed since last update.

KotlinでSpringBootのマルチプロジェクト

Posted at

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にサブプロジェクトを指定します。

setting.gradle
rootProject.name = 'demo'
include 'web', 'share'

build.gradleの修正

まずはプロジェクトrootのbuild.gradleを修正します。

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になりますのでご注意ください。

web/build.gradle
bootJar {
    mainClassName = "com.example.demo.DemoApplicationKt"
}

dependencies {
    implementation project(":share")
}

コード

DemoApplication.kt
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)
}
HelloController.kt
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に追加します。

share/build.gradle
bootJar {
    enabled = false
}
jar {
    enabled = true
}

dependencies {
}

コード

HelloService.kt
package com.example.demo.service

import org.springframework.stereotype.Service

@Service
class HelloService {
    fun say(): String {
        return "Hello!"
    }
}

buildと実行

では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!

参考

Spring Guides -> Creating a Multi Module Project

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2