이 글은 Gradle
에서 자주 쓰이는 플러그인들의 설정을 파일로 분리해 관리하는 방법을 소개합니다.
Gradle 7.4.1
버전에서 작성한 글입니다.
일반적으로 Spring
프로젝트 생성 시 자주 쓰이는 플러그인, 라이브러리가 있는데 각각 Gradle
의 task를 설정해주거나 정의해줘야하는 의존성, 변수들이 있는데 매번 생성 시 정의해야해서 번거로울 때가 많다.
Gradle
은 .gradle
파일을 import할 수 있다. 이를 활용하여 플러그인, 라이브러리별 설정을 파일로 분리하고 적용하는 법을 알아보자.
예시는 멀티 모듈로 작성을 할 것이다. 우리가 만들고 싶은 구조는 다음과 같다.
example
ㄴ example-domain // 도메인 클래스 (spring-data-jpa, querydsl-jpa)
ㄴ example-web // 웹에서 사용되는 api (spring-web, spring-restdocs)
위 구조를 구성하기위해 각각 모듈에 build.gradle
스크립트를 작성해야한다.
여기서 분리할 수 있는 설정을 파일로 분리해보겠다.
폴더를 하나 생성하고 다음과 같이 파일을 생성해보자.
앞으로 관리하게 될 spring
의 스크립트이다.
// scripts/spring_2.7.6.gradle
// 필요 플러그인 // 1
// id 'java'
// id 'org.springframework.boot' version '2.7.6'
// id 'io.spring.dependency-management' version '1.0.15.RELEASE'
apply plugin: 'java-library' // 2
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = '17'
configurations { // 3
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
id
와 version
을 명시해두자. 추후 버전업 시 해당 스크립트가 적용이 불가할 수 있으니 꼭 명시해두자.apply plugin
을 사용하여 이 스크립트에 필요한 플러그인을 적용한다. 이 스크립트가 다른 스크립트에서 적용될 시 apply plugin
에 명시된 플러그인도 같이 적용된다.spring
설정은 최상위 모듈에서 적용되는 경우가 많으므로 전체 모듈에서 사용되면 좋은 설정을 작성해두자. 예시로는 롬복을 적용하였다.이렇게 작성한 스크립트는 다음과 같이 적용할 수 있다.
// build.gradle
plugins { // 1
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
allprojects {
apply from: "$rootDir/scripts/spring_2.7.6.gradle" // 2
}
spring
을 사용하기 위한 플러그인들이다. 위에서 작성한 스크립트를 사용하기 위한 버전을 명시하자.spring
스크립트를 적용한다. spring
설정은 많지가 않아 효율성을 못느낄 수도 있지만 '사내의 spring-boot 2.7.6
의 설정을 공유할 수 있다'라는 관점으로 본다면 나쁘지 않게 느껴질 수도 있다. 필자는 롬복외에도 mapstruct
나 gradle task
를 재정의하는 용도로 사용하고 있다.
spring
설정 분리와 같이 나머지 설정 역시 동일하게 적용할 수 있다. querydsl
설정을 한번 구성해보자.
// scripts/querydsl_jpa_5.0.0.gradle
dependencies {
api "org.springframework.boot:spring-boot-starter-data-jpa"
api "com.querydsl:querydsl-jpa"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
implementation "jakarta.annotation:jakarta.annotation-api"
}
def generated = 'src/main/generated'
sourceSets {
main.java.srcDirs += ["$projectDir/$generated"]
}
tasks.withType(JavaCompile) {
options.annotationProcessorGeneratedSourcesDirectory = provider({
file("$projectDir/$generated")
})
}
clean {
delete file("$projectDir/$generated")
}
example-domain
모듈에 적용해보자
// example-domain/build.gradle
apply from: "$rootDir/scripts/querydsl_jpa_5.0.0.gradle"
dependencies {
// ...필요한 의존성은 따로 작성하면 된다.
}
querydsl
설정에 관련해서는 따로 언급하지않겠다. 중요한 것은 설정을 파일로 분리할 수 있고 그 파일을 사용할 모듈에 적용할 수 있다는 점이다.
추가로 플러그인을 사용하는 경우도 문제없다.
// scripts/asciidoctor_1.5.8.gradle
// 필요 플러그인
// id 'org.asciidoctor.convert' version '1.5.8'
apply plugin: 'org.asciidoctor.convert'
ext {
set('snippetsDir', file("$buildDir/generated-snippets"))
}
dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}
tasks.named('test') {
outputs.dir snippetsDir
useJUnitPlatform()
}
tasks.named('asciidoctor') {
inputs.dir snippetsDir
dependsOn test
}
위 설정은 restdocs
를 사용하기 위한 스크립트이다. 스크립트를 적용하기 위해 org.asciidoctor.convert
플러그인이 필요한데 다음과 같이 적용할 수 있다.
// build.gradle
plugins { // 1
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'org.asciidoctor.convert' version '1.5.8' // 루트 프로젝트에 사용되는 플러그인을 명시해줘야한다.
}
// example-web/build.gradle
apply from: "$rootDir/scripts/asciidoctor_1.5.8.gradle"
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
}
우리는 기존에 web 모듈에서만 사용하는 플러그인을 루트 모듈에 작성하는 경우가 많았을 것이다. 하지만 이렇게 플러그인 설정을 파일로 분리하고 사용할 모듈에 적용시키면 해당 모듈이 무슨 플러그인을 사용하는지 명시적으로 확인할 수 있으므로 구조파악에 도움이 될 수 있다.
이 방법을 무조건 도입할 필요는 없습니다. 단 전사의 gradle
설정을 공유하고 싶거나 가독성을 높이고 싶다면 한번쯤은 도입해보는 것을 추천합니다.
예시의 전체 소스코드는 깃헙에서 확인할 수 있습니다.