스프링은 개발자가 작성한 클래스를 확장하는 프록시를 생성해야 한다. 하지만 코틀린 클래스는 기본 final이다
확장을 위해 자동으로 필요한 스프링 관리 클래스를 열어주는 스프링 플러그인을 빌드 파일에 추가하자
**프록시와 진짜 객체는 둘 다 같은 인터페이스를 구현하거나 같은 클래스를 확장
**한다.
들어오는 요청을 프록시가 가로채고 이 프록시는 서비스가 요구하는 모든 것을 적용한 다음 진짜 객체로 전달한다.
예를 들어 스프링 트랜잭션 프록시는 어떤 메소드 호출을 가로챈 뒤 트랜잭션을 시작한 뒤에 해당 메소드를 호출,
실제 메소드 안에서 일어난 상황에 맞춰 트랜잭션을 커밋하거나 롤백한다
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version PluginVersions.SPRING_BOOT_FRAMEWORK_VERSION
id("io.spring.dependency-management") version PluginVersions.SPRING_DEPENDENCY_MANAGEMENT_VERSION
kotlin("jvm") version PluginVersions.JVM_VERSION // 코틀린 JVM 플러그인을 추가
kotlin("plugin.spring") version PluginVersions.PLUGIN_SPRING_VERSION // 코틀린 스프링 플러그인을 요구
kotlin("plugin.jpa") version PluginVersions.PLUGIN_JPA_VERSION
kotlin("kapt") version PluginVersions.KAPT_VERSION
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation(Dependency.VALIDATION)
implementation(Dependency.WEB)
implementation(Dependency.JACKSON)
implementation(Dependency.JPA)
implementation(Dependency.REFLECT) // 소스 코드가 코틀린으로 작성된 경우 필요
implementation(Dependency.STDLIB_JDK8) // 얘도 똑같음
implementation(Dependency.SPRING_SECURITY)
kapt(Dependency.QUERYDSL_PROCESSOR)
implementation(Dependency.QUERYDSL)
runtimeOnly(Dependency.MYSQL)
implementation(Dependency.OPENFEIGN)
implementation(Dependency.JWT)
implementation(Dependency.FIREBASE_ADMIN)
annotationProcessor(Dependency.PROPERTIES_SCAN)
}
kotlin.sourceSets.main {
kotlin.srcDir("$buildDir/generated/source/kapt/main")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict") // JSR-305과 연관된 널 허용성 @ 지원
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
noArg {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
tasks.getByName<Jar>("jar") {
enabled = false
}