Skip to content

Commit ec76675

Browse files
authored
Merge pull request #26 from team-dodn/springboot4
[DEPENDENCY] Spring Boot 4.0
2 parents 311fc87 + 4bffc5f commit ec76675

File tree

21 files changed

+145
-151
lines changed

21 files changed

+145
-151
lines changed

build.gradle.kts

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2-
31
plugins {
42
kotlin("jvm")
5-
kotlin("kapt")
63
kotlin("plugin.spring") apply false
74
kotlin("plugin.jpa") apply false
85
id("org.springframework.boot") apply false
@@ -11,8 +8,6 @@ plugins {
118
id("org.jlleitschuh.gradle.ktlint") apply false
129
}
1310

14-
java.sourceCompatibility = JavaVersion.valueOf("VERSION_${property("javaVersion")}")
15-
1611
allprojects {
1712
group = "${property("projectGroup")}"
1813
version = "${property("applicationVersion")}"
@@ -24,7 +19,6 @@ allprojects {
2419

2520
subprojects {
2621
apply(plugin = "org.jetbrains.kotlin.jvm")
27-
apply(plugin = "org.jetbrains.kotlin.kapt")
2822
apply(plugin = "org.jetbrains.kotlin.plugin.spring")
2923
apply(plugin = "org.jetbrains.kotlin.plugin.jpa")
3024
apply(plugin = "org.springframework.boot")
@@ -40,65 +34,85 @@ subprojects {
4034

4135
dependencies {
4236
implementation("org.jetbrains.kotlin:kotlin-reflect")
43-
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
4437
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
45-
testImplementation("org.springframework.boot:spring-boot-starter-test")
46-
testImplementation("com.ninja-squad:springmockk:${property("springMockkVersion")}")
4738
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
48-
kapt("org.springframework.boot:spring-boot-configuration-processor")
49-
}
50-
51-
tasks.getByName("bootJar") {
52-
enabled = false
53-
}
54-
55-
tasks.getByName("jar") {
56-
enabled = true
39+
testImplementation("org.springframework.boot:spring-boot-test")
40+
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
41+
testImplementation("org.assertj:assertj-core")
42+
testImplementation("com.ninja-squad:springmockk:${property("springMockkVersion")}")
5743
}
5844

59-
java.sourceCompatibility = JavaVersion.valueOf("VERSION_${property("javaVersion")}")
60-
tasks.withType<KotlinCompile> {
61-
kotlinOptions {
62-
freeCompilerArgs = listOf("-Xjsr305=strict")
63-
jvmTarget = "${project.property("javaVersion")}"
45+
java {
46+
toolchain {
47+
languageVersion = JavaLanguageVersion.of("${property("javaVersion")}")
6448
}
6549
}
6650

67-
tasks.test {
68-
useJUnitPlatform {
69-
excludeTags("develop", "restdocs")
51+
kotlin {
52+
compilerOptions {
53+
freeCompilerArgs.addAll("-Xjsr305=strict", "-Xannotation-default-target=param-property")
7054
}
7155
}
7256

73-
tasks.register<Test>("unitTest") {
74-
group = "verification"
75-
useJUnitPlatform {
76-
excludeTags("develop", "context", "restdocs")
77-
}
57+
tasks.named<Jar>("bootJar").configure {
58+
enabled = false
7859
}
7960

80-
tasks.register<Test>("contextTest") {
81-
group = "verification"
82-
useJUnitPlatform {
83-
includeTags("context")
84-
}
61+
tasks.named<Jar>("jar").configure {
62+
enabled = true
8563
}
8664

87-
tasks.register<Test>("restDocsTest") {
88-
group = "verification"
65+
tasks.test {
8966
useJUnitPlatform {
90-
includeTags("restdocs")
67+
excludeTags("develop", "restdocs")
9168
}
9269
}
9370

94-
tasks.register<Test>("developTest") {
95-
group = "verification"
96-
useJUnitPlatform {
97-
includeTags("develop")
71+
testing {
72+
suites {
73+
named<JvmTestSuite>("test") {
74+
targets {
75+
register("unitTest") {
76+
testTask.configure {
77+
group = "verification"
78+
useJUnitPlatform {
79+
excludeTags("develop", "context", "restdocs")
80+
}
81+
}
82+
}
83+
84+
register("contextTest") {
85+
testTask.configure {
86+
group = "verification"
87+
useJUnitPlatform {
88+
includeTags("context")
89+
}
90+
}
91+
}
92+
93+
register("restDocsTest") {
94+
testTask.configure {
95+
group = "verification"
96+
useJUnitPlatform {
97+
includeTags("restdocs")
98+
}
99+
}
100+
}
101+
102+
register("developTest") {
103+
testTask.configure {
104+
group = "verification"
105+
useJUnitPlatform {
106+
includeTags("develop")
107+
}
108+
}
109+
}
110+
}
111+
}
98112
}
99113
}
100114

101-
tasks.getByName("asciidoctor") {
115+
tasks.named("asciidoctor").configure {
102116
dependsOn("restDocsTest")
103117
}
104118
}

core/core-api/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tasks.getByName("bootJar") {
1+
tasks.named<Jar>("bootJar").configure {
22
enabled = true
33
}
44

5-
tasks.getByName("jar") {
5+
tasks.named<Jar>("jar").configure {
66
enabled = false
77
}
88

@@ -15,5 +15,5 @@ dependencies {
1515

1616
testImplementation(project(":tests:api-docs"))
1717

18-
implementation("org.springframework.boot:spring-boot-starter-web")
18+
implementation("org.springframework.boot:spring-boot-starter-webmvc")
1919
}

core/core-api/src/main/kotlin/io/dodn/springboot/core/api/config/AsyncConfig.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import java.util.concurrent.Executor
1111
@Configuration
1212
@EnableAsync
1313
class AsyncConfig : AsyncConfigurer {
14-
1514
@Bean
1615
override fun getAsyncExecutor(): Executor {
1716
val executor = ThreadPoolTaskExecutor()

core/core-api/src/main/kotlin/io/dodn/springboot/core/api/controller/v1/ExampleController.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.dodn.springboot.core.api.controller.v1
22

33
import io.dodn.springboot.core.api.controller.v1.request.ExampleRequestDto
4+
import io.dodn.springboot.core.api.controller.v1.response.ExampleItemResponseDto
45
import io.dodn.springboot.core.api.controller.v1.response.ExampleResponseDto
56
import io.dodn.springboot.core.domain.ExampleData
67
import io.dodn.springboot.core.domain.ExampleService
@@ -11,6 +12,8 @@ import org.springframework.web.bind.annotation.PostMapping
1112
import org.springframework.web.bind.annotation.RequestBody
1213
import org.springframework.web.bind.annotation.RequestParam
1314
import org.springframework.web.bind.annotation.RestController
15+
import java.time.LocalDate
16+
import java.time.LocalDateTime
1417

1518
@RestController
1619
class ExampleController(
@@ -22,14 +25,14 @@ class ExampleController(
2225
@RequestParam exampleParam: String,
2326
): ApiResponse<ExampleResponseDto> {
2427
val result = exampleExampleService.processExample(ExampleData(exampleValue, exampleParam))
25-
return ApiResponse.success(ExampleResponseDto(result.data))
28+
return ApiResponse.success(ExampleResponseDto(result.data, LocalDate.now(), LocalDateTime.now(), ExampleItemResponseDto.build()))
2629
}
2730

2831
@PostMapping("/post")
2932
fun examplePost(
3033
@RequestBody request: ExampleRequestDto,
3134
): ApiResponse<ExampleResponseDto> {
3235
val result = exampleExampleService.processExample(request.toExampleData())
33-
return ApiResponse.success(ExampleResponseDto(result.data))
36+
return ApiResponse.success(ExampleResponseDto(result.data, LocalDate.now(), LocalDateTime.now(), ExampleItemResponseDto.build()))
3437
}
3538
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
package io.dodn.springboot.core.api.controller.v1.response
22

3+
import java.time.LocalDate
4+
import java.time.LocalDateTime
5+
36
data class ExampleResponseDto(
47
val result: String,
8+
val date: LocalDate,
9+
val datetime: LocalDateTime,
10+
val items: List<ExampleItemResponseDto>,
511
)
12+
13+
data class ExampleItemResponseDto(
14+
val key: String,
15+
) {
16+
companion object {
17+
fun build(): List<ExampleItemResponseDto> {
18+
return listOf(ExampleItemResponseDto("1"), ExampleItemResponseDto("2"))
19+
}
20+
}
21+
}

core/core-api/src/main/kotlin/io/dodn/springboot/core/support/error/ErrorMessage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.dodn.springboot.core.support.error
22

3-
data class ErrorMessage private constructor(
3+
class ErrorMessage private constructor(
44
val code: String,
55
val message: String,
66
val data: Any? = null,

core/core-api/src/main/kotlin/io/dodn/springboot/core/support/response/ApiResponse.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package io.dodn.springboot.core.support.response
33
import io.dodn.springboot.core.support.error.ErrorMessage
44
import io.dodn.springboot.core.support.error.ErrorType
55

6-
data class ApiResponse<T> private constructor(
6+
class ApiResponse<T> private constructor(
77
val result: ResultType,
88
val data: T? = null,
99
val error: ErrorMessage? = null,

core/core-api/src/test/kotlin/io/dodn/springboot/core/api/controller/v1/ExampleControllerTest.kt

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
11
package io.dodn.springboot.core.api.controller.v1
22

3+
import com.fasterxml.jackson.module.kotlin.jsonMapper
34
import io.dodn.springboot.core.api.controller.v1.request.ExampleRequestDto
45
import io.dodn.springboot.core.domain.ExampleResult
56
import io.dodn.springboot.core.domain.ExampleService
67
import io.dodn.springboot.test.api.RestDocsTest
7-
import io.dodn.springboot.test.api.RestDocsUtils.requestPreprocessor
8-
import io.dodn.springboot.test.api.RestDocsUtils.responsePreprocessor
98
import io.mockk.every
109
import io.mockk.mockk
11-
import io.restassured.http.ContentType
1210
import org.junit.jupiter.api.BeforeEach
1311
import org.junit.jupiter.api.Test
14-
import org.springframework.http.HttpStatus
12+
import org.springframework.http.MediaType
1513
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document
14+
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get
15+
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post
16+
import org.springframework.restdocs.operation.preprocess.Preprocessors
1617
import org.springframework.restdocs.payload.JsonFieldType
1718
import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
1819
import org.springframework.restdocs.payload.PayloadDocumentation.requestFields
1920
import org.springframework.restdocs.payload.PayloadDocumentation.responseFields
2021
import org.springframework.restdocs.request.RequestDocumentation
2122
import org.springframework.restdocs.request.RequestDocumentation.parameterWithName
2223
import org.springframework.restdocs.request.RequestDocumentation.queryParameters
24+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
2325

2426
class ExampleControllerTest : RestDocsTest() {
2527
private lateinit var exampleService: ExampleService
26-
private lateinit var controller: ExampleController
2728

2829
@BeforeEach
2930
fun setUp() {
3031
exampleService = mockk()
31-
controller = ExampleController(exampleService)
32-
mockMvc = mockController(controller)
32+
mockMvc = mockController(ExampleController(exampleService))
3333
}
3434

3535
@Test
3636
fun exampleGet() {
37-
every { exampleService.processExample(any()) } returns ExampleResult("BYE")
37+
every { exampleService.processExample(any()) } returns ExampleResult("BYE_GET")
3838

39-
given()
40-
.contentType(ContentType.JSON)
41-
.queryParam("exampleParam", "HELLO_PARAM")
42-
.get("/get/{exampleValue}", "HELLO_PATH")
43-
.then()
44-
.status(HttpStatus.OK)
45-
.apply(
39+
mockMvc.perform(
40+
get("/get/{exampleValue}", "HELLO_PATH")
41+
.param("exampleParam", "HELLO_PARAM")
42+
.contentType(MediaType.APPLICATION_JSON),
43+
)
44+
.andExpect(status().isOk)
45+
.andDo(
4646
document(
4747
"exampleGet",
48-
requestPreprocessor(),
49-
responsePreprocessor(),
48+
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
49+
Preprocessors.preprocessResponse(Preprocessors.prettyPrint()),
5050
RequestDocumentation.pathParameters(
5151
parameterWithName("exampleValue").description("ExampleValue"),
5252
),
@@ -55,7 +55,11 @@ class ExampleControllerTest : RestDocsTest() {
5555
),
5656
responseFields(
5757
fieldWithPath("result").type(JsonFieldType.STRING).description("ResultType"),
58-
fieldWithPath("data.result").type(JsonFieldType.STRING).description("Result Date"),
58+
fieldWithPath("data.result").type(JsonFieldType.STRING).description("Result Data"),
59+
fieldWithPath("data.date").type(JsonFieldType.STRING).description("Result Date"),
60+
fieldWithPath("data.datetime").type(JsonFieldType.STRING).description("Result Datetime"),
61+
fieldWithPath("data.items").type(JsonFieldType.ARRAY).description("Result Items"),
62+
fieldWithPath("data.items[].key").type(JsonFieldType.STRING).description("Result Item"),
5963
fieldWithPath("error").type(JsonFieldType.NULL).ignored(),
6064
),
6165
),
@@ -64,25 +68,29 @@ class ExampleControllerTest : RestDocsTest() {
6468

6569
@Test
6670
fun examplePost() {
67-
every { exampleService.processExample(any()) } returns ExampleResult("BYE")
71+
every { exampleService.processExample(any()) } returns ExampleResult("BYE_POST")
6872

69-
given()
70-
.contentType(ContentType.JSON)
71-
.body(ExampleRequestDto("HELLO_BODY"))
72-
.post("/post")
73-
.then()
74-
.status(HttpStatus.OK)
75-
.apply(
73+
mockMvc.perform(
74+
post("/post")
75+
.contentType(MediaType.APPLICATION_JSON)
76+
.content(jsonMapper().writeValueAsString(ExampleRequestDto("HELLO_BODY"))),
77+
)
78+
.andExpect(status().isOk)
79+
.andDo(
7680
document(
7781
"examplePost",
78-
requestPreprocessor(),
79-
responsePreprocessor(),
82+
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
83+
Preprocessors.preprocessResponse(Preprocessors.prettyPrint()),
8084
requestFields(
8185
fieldWithPath("data").type(JsonFieldType.STRING).description("ExampleBody Data Field"),
8286
),
8387
responseFields(
8488
fieldWithPath("result").type(JsonFieldType.STRING).description("ResultType"),
85-
fieldWithPath("data.result").type(JsonFieldType.STRING).description("Result Date"),
89+
fieldWithPath("data.result").type(JsonFieldType.STRING).description("Result Data"),
90+
fieldWithPath("data.date").type(JsonFieldType.STRING).description("Result Date"),
91+
fieldWithPath("data.datetime").type(JsonFieldType.STRING).description("Result Datetime"),
92+
fieldWithPath("data.items").type(JsonFieldType.ARRAY).description("Result Items"),
93+
fieldWithPath("data.items[].key").type(JsonFieldType.STRING).description("Result Item"),
8694
fieldWithPath("error").type(JsonFieldType.STRING).ignored(),
8795
),
8896
),

gradle.properties

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ applicationVersion=0.0.1-SNAPSHOT
55
projectGroup=io.dodn.springboot
66

77
### Project dependency versions ###
8-
kotlinVersion=1.9.25
8+
kotlinVersion=2.2.21
99
javaVersion=21
1010

1111
### Plugin dependency versions ###
12-
asciidoctorConvertVersion=3.3.2
13-
ktlintVersion=13.0.0
12+
asciidoctorConvertVersion=4.0.5
13+
ktlintVersion=14.0.1
1414

1515
### Spring dependency versions ###
16-
springBootVersion=3.5.3
16+
springBootVersion=4.0.0
1717
springDependencyManagementVersion=1.1.7
18-
springCloudDependenciesVersion=2025.0.0
18+
springCloudDependenciesVersion=2025.1.0
1919

2020
### External dependency versions ###
21-
springMockkVersion=4.0.2
22-
sentryVersion=8.17.0
21+
springMockkVersion=5.0.1
22+
sentryVersion=8.27.1

gradle/wrapper/gradle-wrapper.jar

181 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)