728x90
스프링 부트 스타터
| 이름 | 설명 |
| spring-boot-starter-web | SpringMVC 기반의 웹 애플리케이션 스타터, 임베디드 톰캣 포함 |
| spring-boot-starter-security | SpringSecurity 관련 설정과 라이브러리 포함 |
| spring-boot-starter-data-jpa | SpringTransaction, Hibernate, 히카리CP 등 포함 |
| spring-boot-starter-test | JUnit, Mokito, AssertJ 와 같은 테스팅 프레임워크 포함 |
| spring-boot-starter-webflux | Reactive 프레임워크인 ProjectReactor, Netty를 포함 |
- 스프링 부트 스타터는 스프링 부트 기반의 애플리케이션에 다른 스프링 프로젝트를 쉽게 추가할 수 있도록 만들어진 라이브러리이다.
- 각각의 스타터에는 스프링 프로젝트와 프로젝트에서 필요로 하는 라이브러리가 같이 포함되어 있다.
- 스프링 부트 스타터를 사용하면, 스타터 외 필요한 라이브러리를 따로 추가, 관리할 필요가 없다.
- 스프링 부트 공식 스타터는 명명 규칙에 따라 spring-boot-starter-* 와 같은 형태이다.
서드 파티 스프링 부트 스타터
- 공식 스프링 부트 스타터가 아닌 서드 파티 스프링 부트 스타터가 있다.
- 외부 프로젝트에서 스프링 부트와 연동하기 위해 직접 만든 커스텀 스타터를 의미하며, sprint-boot-starter-*이라는 이름으로 만들 수 없다.
- 서드 파티 스타터는 *-spring-boot-starter와 같은 명명규칙을 사용한다.
- MyBatis 같은 경우 mybatis-spring-boot-starter라는 이름의 스타터를 직접 만들어서 제공
커스텀 스프링 부트 스타터 만들기
https://github.com/digimon1740/fastcampus-custom-spring-boot-starter
GitHub - digimon1740/fastcampus-custom-spring-boot-starter
Contribute to digimon1740/fastcampus-custom-spring-boot-starter development by creating an account on GitHub.
github.com
- handgame : 가위바위보 게임의 상세 구현이 포함된 라이브러리
- handgame-spring-boot-autoconfigure : handgame 라이브러리의 자동 설정이 포함
- handgame-spring-boot-starter : handgame, handgame-spring-boot-autoconfigure을 합친 커스턴 spring-boot-starter
- handgame-spring-boot-app : handgame-spring-boot-starter를 사용하는 스프링 부트 애플리케이션
최상위 build.gradle
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id("org.springframework.boot") version "2.7.0" apply false
id("io.spring.dependency-management") version "1.0.11.RELEASE"
id("maven-publish")
kotlin("jvm") version "1.6.21"
kotlin("plugin.spring") version "1.6.21"
kotlin("kapt") version "1.6.21"
}
allprojects {
group = "com.fastcampus.springboot"
version = "1.0-SNAPSHOT"
repositories {
mavenLocal()
mavenCentral()
}
}
subprojects {
apply(plugin = "kotlin")
apply(plugin = "kotlin-kapt")
apply(plugin = "kotlin-spring")
apply(plugin = "maven-publish")
apply(plugin = "io.spring.dependency-management")
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}
dependencyManagement {
imports {
mavenBom(SpringBootPlugin.BOM_COORDINATES)
}
}
}
- maven-publish는 Maven-repository에 배포할 수 있게 하는 기능을 하는 plugin으로, 스타터 프로젝트를 로컬 maven-repository에 배포해서, handgame-spring-boot-app에서 사용할 예정이다.
- allproject는 최상위 프로젝트를 포함한 전체 프로젝트에서 사용하는 빌드 구성
- subprojects는 settings.gradle.kts에서 include에 감싸진 프로젝트의 빌드를 구성
handgame/Handgame.kt
class Handgame {
fun play(player: GameCommand): Pair<GameResult, GameCommand> {
val opponent = GameCommand.values()[Random().nextInt(3)]
return if (player == opponent) {
return Pair(GameResult.동점, player)
} else if (player == GameCommand.바위 && opponent == GameCommand.가위) {
return Pair(GameResult.승리, GameCommand.가위)
} else if (player == GameCommand.가위 && opponent == GameCommand.보) {
return Pair(GameResult.승리, GameCommand.보)
} else if (player == GameCommand.보 && opponent == GameCommand.바위) {
return Pair(GameResult.승리, GameCommand.바위)
} else Pair(GameResult.패배, opponent)
}
}
enum class GameCommand(num: Int) {
바위(0), 가위(1), 보(2);
}
enum class GameResult {
동점, 승리, 패배
}
- 사용자의 커맨드를 전달받아 가위바위보 게임 결과를 리턴한다.
handgame-spring-boot-autoconfigure
build.gradle.kts
dependencies {
kapt("org.springframework.boot:spring-boot-autoconfigure-processor")
kapt("org.springframework.boot:spring-boot-configuration-processor")
api(project(":handgame"))
implementation("org.springframework.boot:spring-boot")
implementation("org.springframework.boot:spring-boot-autoconfigure")
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
}
}
}
- kapt는 코틀린에서 애노테이션 프로세서(컴파일 타임에 애노테이션을 읽어서 동적으로 코드를 생성하거나 변경하는 기능을 한다)가 동작하도록 하는 플러그인이다.
- hangame 프로젝트의 의존성을 추가해 자동 설정 클래스에서 Handgame.kt 클래스를 불러올 수 있게 설정
HandgameAutoconfigure.kt
@AutoConfiguration
@ConditionalOnClass(Handgame::class)
@ConditionalOnProperty(prefix = "my.handgame", name = ["enabled"], havingValue = "true")
class HandgameAutoconfiguration {
@Bean
@ConditionalOnMissingBean
fun handgame() = Handgame()
}
- Handgame 클래스의 인스턴스를 스프링 빈에 등록하는 자동 설정 클래스
- 자동 설정 클래스는 설정 클래스임을 나타내기 위해 @Configuration 애노테이션을 선언
- @ConditionalOnProperty를 사용해 "my.handgame.enabled=true" 일 경우에만 해당 설정 클래스가 동작하도록 로드 시점을 조정
- 사용자가 handgame 빈을 재정의 할 경우 충돌이 발생하므로, @ConditionalOnMissingBean을 사용해서 handgame 빈이 존재하지 않는 경우에만 빈을 로드
handgame-spring-boot-starter/build.gradle.kts
dependencies {
api(project(":handgame"))
api(project(":handgame-spring-boot-autoconfigure"))
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
}
}
}
- handgame 라이브러리와 자동 설정 구현체인 handgame-spring-boot-autoconfigure에 대한 의존성 추가
handgame-spring-boot-app
build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter")
// 우리가 만든 커스텀 스프링 부트 스타터
implementation("com.fastcampus.springboot:handgame-spring-boot-starter:1.0-SNAPSHOT")
}
HandgameApplication.kt
@SpringBootApplication
class HandgameApplication (
// 의존성 주입된 Handgame
val handgame: Handgame
) : CommandLineRunner {
val logger = LoggerFactory.getLogger(Handgame::class.java)
override fun run(vararg args: String) {
val myCommands = buildList {
add(GameCommand.바위)
add(GameCommand.가위)
add(GameCommand.보)
add(GameCommand.가위)
}
myCommands.forEach {
val (result, opponentCommand) = handgame.play(it)
logger.info("나 : {}, 상대방 : {}, 결과 : {}", it, opponentCommand, result)
}
}
}
fun main(args: Array<String>) {
runApplication<HandgameApplication>(*args)
}
- 순서대로 handgame > handgame-spring-boot-autoconfigure > handgame-spring-boot-starter 순서대로 배포한다.
- Tasks > publishing > publishingMavenLocal을 눌러 배포하면 된다.
- 이대로 실행하면 오류가 발생하는데, program arguments로 --debug 옵션을 주면, 현재 설정된 자동 설정과 적용되지 않은 자동 설정을 확인할 수 있다.
- 문제는 자동 설정 클래스를 제작할 때 my.handgame.enabled 프로퍼티가 true인 경우에만 동작하게 했기 때문이다.
- application.properties에 "my.handgame.enabled=true"를 추가한 뒤 실행하면 잘 동작한다
728x90
'실무 프로젝트로 배우는 Kotlin & Spring > 스프링 부트 스타트' 카테고리의 다른 글
| 스프링 부트 자동 설정 (0) | 2022.10.23 |
|---|---|
| 스프링 이니셜라이저 (0) | 2022.10.23 |
| 스프링 부트 (0) | 2022.10.23 |