Spring Boot 3. x 멀티 모듈 프로젝트 구성하기
이 글을 쓴 계기는 회사 내에 프로젝트에서 Spring Boot 2. x 버전에서 3. x 이상의 버전으로 마이그레이션 많은 부분이 Deprecated 되었고, property나 yml들의 구성 방식 변경, Java 17 이상의 버전 요구, security의 configure에서 filter Chain 방식으로 구성 변경, log back과 같은 파일들을 보안상 사용하지 못하게 하면서 새로운 버전에 대한 멀티 모듈 설정이나 구성 환경에 대해 확실하게 이해하기 위해 작성했다. property를 작성하는 방식과 yml 방식이 있는데, 한번 구성해 두면 더 깔끔한 프로젝트를 완성 시킬 수 있으니 3버전 이후로 바뀐 구성으로 진행해 보고 싶어서 정리하였습니다.
프로젝트 생성 및 설치
따로 프로젝트가 없다면 해당 링크로 들어가 자신이 사용할 라이브러리들을 찾아 설정 후 Spring Boot 3버전 프로젝트를 생성 시켜줍니다.
사용하지 않는 src 파일 삭제 및 모듈 생성
프로젝트 생성 후 아래와 같이 멀티 모듈 프로젝트 경로를 만들기 위해 부모 프로젝트에 있는 src 파일을 삭제 시켜주고, 각 모듈을 생성한다. core에는 DB나 AWS 환경들 같은 공통 값을 구성하고, API에는 각 profile 환경에 맞게 core와 연동시켜 구성 파일들을 작성합니다.
멀티 모듈 gradle 환경 구성하기
내가 작성했던 gradle은 JPA와 QueryDsl 라이브러리를 추가한 상태이며, Spring Boot 3버전 이후에는 java 17 이상이 되어야 사용할 수 있으므로 17버전으로 구성하였습니다. 또한 3버전 이후 Java EE에서 Jakarta EE를 지원하게 되어서 Jakarta가 붙은 버전을 사용해야 합니다. 이 부분은 QueryDsl 라이브러리에 Jakarta가 붙은 모습을 확인 할 수 있다. core 모듈은 애플리케이션을 실행할 필요가 없기 때문에 bootJar. enabled = false로 설정해 줍니다. subprojects 부분에는 자식 모듈들에 공통되는 라이브러리를 추가해서 각 모듈에 적용될 수 있도록 합니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.7'
id 'io.spring.dependency-management' version '1.1.4'
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}
group = 'com.project'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
bootJar.enabled = false
subprojects {
group = 'com.project'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
apply plugin: 'java'
// build.gradle에서 api() 를 사용하려면 java-library 사용
apply plugin: 'java-library'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
//queryDSL 설정
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
//h2
runtimeOnly 'com.h2database:h2'
}
tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
}
test {
useJUnitPlatform()
}
tasks.named('bootJar') { //빌드할 때 bootjar 파일로 하겠다는 의미
enabled = false
}
tasks.named('jar') { //빌드할 때 jar 파일로 하겠다는 의미
enabled = true
}
tasks.named('test') {
useJUnitPlatform()
}
}
사용할 모듈의 application.yml 구성하기
아래와 같이 active 설정을 해주고, 각 환경 yml을 작성하여 on-profile에 아래와 같이 구성합니다.
core에는 db 정보 또는 key 값 같은 부분들을 작성하여 등록하고, API 부분에는 아래와 같이 작성하여 실행해 주었고, config에는 core-yml을 공통부분으로 import 시켜 API 모듈의 공통부분으로 적용하였습니다. 다른 방법으로는 profile group을 각각 설정하여 include 방식처럼 import가 되도록 설정할 수 있습니다.
실행 환경을 구성할 때는 profiles의 active를 설정하여 원하는 환경에 맞게 실행되는 모습을 볼 수 있다. 나는 작성할 때 profiles를 profile로 등록하여 한참 헤맸고 다른 방법으로는 인텔리 제이에서 직접 active 환경 변수를 등록하는 방법이 있는데 간단하니 따로 작성하지 않겠습니다.
#common
spring:
profiles:
active: local
config:
import: application-core.yml
jwt:
secretKey: //secretKey
servlet:
multipart:
max-file-size: 10MB
--- # local
spring:
config:
activate:
on-profile: local
--- # dev
spring:
config:
activate:
on-profile: dev
--- # prod
spring:
config:
activate:
on-profile: prod
실행 환경 구성 및 확인
위 내용을 다 완료 했으면 해당 Application Runner를 Component로 등록하여 실행될 때 어떤 profile 환경이 구성되어 실행되고 있는지 편리하게 확인 할 수 있으니 참고하여 실행 테스트를 해보기를 바랍니다.
@Component
public class ApplicationRunner implements org.springframework.boot.ApplicationRunner {
private final Environment environment;
// TODO :: profile yml 적용 테스트
public ApplicationRunner(Environment environment) {
this.environment = environment;
}
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("===================다중 프로파일 테스트===================");
System.out.println("실행 profiles : "+ Arrays.toString(environment.getActiveProfiles()));
System.out.println("드라이버 환경 : " + environment.getProperty("spring.datasource.driver-class-name"));
System.out.println("url : " + environment.getProperty("spring.datasource.url"));
System.out.println("DB username : " + environment.getProperty("spring.datasource.username"));
System.out.println("DB password : " + environment.getProperty("spring.datasource.password"));
System.out.println("port : " + environment.getProperty("server.port"));
System.out.println("====================================================");
}
}
이것으로 Spring Boot 3. x 버전에 대한 profile설정을 완료했으며 실행되는 결과물을 볼 수 있었습니다. 다음 글에는 해당 환경으로 구성된 Spring Security, Json Web Token에 개념과 연동되는 구성 과정에 대해 알아보고 configure로 설정하는게 아닌 변경된 Filter Chain으로 구성하는 글을 작성하도록 하겠습니다.
'Spring' 카테고리의 다른 글
[JPA] JPA 개념과 기본 설정 가이드 (0) | 2024.01.29 |
---|---|
[Spring] SpringBoot JWT 로그인 구현 가이드 (1) | 2024.01.26 |
[Spring] SpringBoot Swagger 연동 (3.x ver) (0) | 2024.01.10 |
[Spring] SpringBoot Sequrity + JWT 구현 (3.x ver) (0) | 2024.01.06 |
[Spring] Spring Security는 무엇일까? (0) | 2024.01.04 |