반응형
Springboot로 API 서버 애플리케이션 등을 개발할 때 Multi-module을 채택 할 수 있습니다.
(요즘 핫하다고는 못하겠네요. 주목 받은지 꽤 시간이 흐른듯합니다 ㅎㅎ)
아래와 같은 Multi-module로 된 프로젝트가 있습니다.
Front API와 Backoffice API를 개발하다보면
같은 도메인(예: DB Entity 및 Repository)을 사용할 때가 생길 수 있습니다.
중복코드가 많아 질 수 있는 상황입니다.
아래와 같이 Domain 모듈로 분리해주면 좀 더 세련된 코딩을 할 수 있을 것 같습니다.
이번 포스팅에서는 Multi-module에서 Domain(DB 의존성) 모듈을 분리하여 세팅할 때 필요한 작업을 정리해봅니다.
1. 프로젝트 구조
Project의 각 Module 구조는 아래와 같습니다.
├── backoffice-api
├── front-api
├── core
├── domain
├── gradle.properties
├── gradlew
├── build.gradle.kts
└── settings.gradle.kts
build.gradle.kts는 아래와 같습니다.
rootProject.name = "my-project"
include("backoffice-api")
include("front-api")
include("core")
include("domain")
2. Domain 모듈 작성
아래와 같이 domain 내에 build.gradle.kts를 작성합니다.
plugins {
id("java")
}
group = "me.basket"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
api("org.springframework.boot:spring-boot-starter-data-jpa")
api("mysql:mysql-connector-java:8.0.33")
}
// (중략...)
- domain 모듈에서 jpa 의존성 추가시 implementation이 아닌 api로 해줘야함.
- 만약 implementation으로 하게 되면, backoffice-api 모듈에서 jpa의 API(관련 annotaion 등)을 참조하지 못하게 됨.
<implementation과 api 의 차이점>
Gradle에서 implementation과 api 구성은 종속성을 선언하는 데 사용되지만, 다른 범위를 갖습니다
implementation으로 선언된 종속성은 선언된 모듈에서만 보이며 하위 모듈로 전이되지 않습니다.
내부 구현 세부 정보에 사용되며 해당 모듈의 소비자에 노출되지 않습니다.
api로 선언된 종속성은 선언된 모듈과 해당 모듈에 의존하는 모듈 모두에서 볼 수 있습니다.
모듈의 공개 API의 일부이며 해당 모듈의 소비자에 노출됩니다.
Domain 모듈의 구조는 아래와 같이 구성했습니다.
└── me
└── basket
└── example
├── base
│ ├── BaseEntity.kt
└── domain
├── enums
│ └── MemberCategory.kt
├── entity
│ ├── MemberEntity.kt
└── repository
├── MemberRepository.kt
3. Api 모듈 작성
아래와 같이 backoffice-api 또는 front-api 의 build.gradle.kts를 작성해줍니다.
plugins {
id("java")
}
group = "me.basket"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(project(":core"))
implementation(project(":domain"))
/* Springboot */
implementation("org.springframework.boot:spring-boot-starter-web:3.1.4")
implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.4")
// (...중략)
}
- domain 모듈 의존성 추가에 implementation을 사용해줌.
4. Application Class 수정
위와 같이 domain을 모듈로 다른 패키지로 분리하게 되면
아래와 같은 작업을 해줘야합니다.
@SpringBootApplication
@EnableJpaRepositories(basePackages = ["me.basket.example.domain"])
@EntityScan(basePackages = ["me.basket.example.domain"])
class BackofficeApiApplication
fun main(args: Array<String>) {
runApplication<BackofficeApiApplication>(*args)
}
- 다른 패키지(domain 모듈 내)에 위치해 있는 @Entity, @Repository 등을 스캔이 필요.
- 이를 위해서는 @EnableJpaRepository, @EntityScan을 통해 수동으로 패키지를 지정해줘야함.
위와 같이 간단하게 Domain을 모듈로 분리하고
의존성 관리를 좀 더 세련되게 할 수 있겠습니다.
반응형
'개발 이야기 > Springboot' 카테고리의 다른 글
JdbcTemplate로 batchUpdate 사용해보기 (0) | 2024.05.28 |
---|---|
Springbatch에서 메타테이블 없이 실행(Springbatch 5) (0) | 2024.03.19 |
Springboot Webflux에서 blocking 감지하기(with BlockHound) (0) | 2024.02.08 |
Springboot에서 P6Spy 통해 쿼리 로깅 (0) | 2024.02.03 |
Springboot에서 ArchUnit 사용해서 아키텍처 테스트 (0) | 2024.01.27 |