hello world
when you access / hello
with GET.Getting Started · Creating a Multi Module Project
hello
directly under the project to
setting.gradle` directly under the project.setting.gradle
rootProject.name = 'demo'
include 'hello'
Create build.gradle
directly under the hello directory and write as follows
build.gralde
buildscript {
ext {
kotlinVersion = '1.3.10'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
}
}
ext {
springBootVersion = '2.1.0.RELEASE'
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('com.fasterxml.jackson.module:jackson-module-kotlin')
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
}
}
You don't need to use ʻorg.springframework.boot's gradle plugin for submodules, but you need
spring-boot-dependencies, so use
dependency-managementand
mavenBom`
Maybe Kotlin plugins should also use dependency-management
and mavenBom
Added the description of ʻimplementation project (': hello')` to the dependencies of build.gradle directly under the project.
...
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('com.fasterxml.jackson.module:jackson-module-kotlin')
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation project(':hello')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
src / main / kotlin
directory under the hello directorycom.example.demo.hello
under the src / main / kotlin
directory.com.example.demo.hello
packagepackage com.example.demo.hello
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
class Controller {
@GetMapping("/hello")
fun hello(
@RequestParam(required = false, defaultValue = "world") name: String
): String {
return "hello $name"
}
}
http: // localhost: 8080 / hello
with a browser and check that hello world
is displayed.If you want to write a test using Spring function like using mockMvc in a module, you need to prepare a class with @SpringBootApplication
.
Sample unit test using Spring function
@ExtendWith(SpringExtension::class)
@WebMvcTest
class ControllerTest(@Autowired val mockMvc: MockMvc) {
@Test
fun test() {
// /Request parameter name to hello=If you request with test
//The status is 200 and the response is"hello test"Confirm that
val request = MockMvcRequestBuilders.get("/hello")
.param("name", "test")
mockMvc.perform(request)
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.content().string("hello test"))
}
@SpringBootApplication
internal class TestConfiguration
}
If you do not prepare a class with @SpringBootApplication
, you will get this error message
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
The class with @SpringBootApplication
may be prepared as a separate file.
There is such a description in Official Tutorial linked for reference.
In the sample above we have configured the
service.message
for the test using the default attribute of the@SpringBootTest
annotation. It is not advisable to putapplication.properties
in a library because there might be a clash at runtime in the application that uses it (only oneapplication.properties
is ever loaded from the classpath). You could putapplication.properties
in the test classpath, but not include it in the jar, for instance by placing it insrc/test/resources
.
It is not recommended to create application.properties (yml) under each module because it conflicts.
As a test, I prepared application.properties (yml) in the project root and in the hello module in this example and tried to see how it works.
Prepare an entry point to display the value of application.properties (yml) in Controller
@RestController
class Controller {
@Value("\${hoge}")
private val hoge: String? = null
@Value("\${fuga}")
private val fuga: String? = null
...
@GetMapping("/test")
fun test(): String {
return "$hoge $fuga"
}
}
hoge: hogehoge
fuga: fugafuga
When I ran the application in this state and accessed http: // localhost: 8080 / test, hogehoge fugafuga
was displayed.
It works fine even if there is application.properties (yml) only in the module
In the project root
hoge: hoge
fuga: fuga
In the hello module
hoge: hogehoge
fuga: fugafuga
When I ran the application in this state and accessed http: // localhost: 8080 / test, hoge fuga
was displayed.
Priority was given to setting the project root
In the project root
hoge: hoge
In the hello module
hoge: hogehoge
fuga: fugafuga
If you try to run the application in this state, it will crash and an execution error will occur.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'controller': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'fuga' in value "${fuga}"
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'fuga' in value "${fuga}"
...
It seems unlikely that you will get the missing items from application.properties (yml) in another module.
Even if you create application.properties (yml) for each module and prepare your own setting values, only one application.properties (yml) is prioritized. It seems unlikely that you will get the settings of other modules. If so, it seems better to manage it in the project root or in the main module.
https://github.com/eno314/SpringModuleSample
Recommended Posts