빌드도구
는 빌드의 모든 과정(컴파일, 테스트, 배포, 문서화 등의 작업을 포함하는 절차)을 자동으로 처리할 수 있도록 도와주는 것이다. 즉 개발을 좀 더 쉽게 할 수 있도록 도움을 준다! 빌드 도구 중 하나가 Gradle이다.
Gradle에서 사용되는 언어
로는 그루비 기반의 gradle dsl(Domain-Specific Languages, 도메인 특화 언어)를 사용한다.
settings.gradle 파일
: 프로젝트의 구성 정보를 기록하는 파일이다.
어떤 하위 프로젝트들이 어떤 관계로 구성되어 있는지를 기술하면 된다.
build.gradle 파일
: 의존성이나 플러그인 설정 등을 하는 파일이다.
빌드 작업에 필요한 기본 설정, 동작 등을 기술하면 된다.
- 그렇다면
gradle의 흐름!?
을 정리해보자!
: 우선 settings.gradle 파일을 참고해 프로젝트의 구조를 파악하고, build.gradle 파일을 통해 개별 프로젝트를 빌드하는 방식으로 동작한다.
plugins
: 프로젝트를 빌드하기 위해 여러가지 작업(컴파일, jar 파일 생성, ...)을 처리해줘야 하는데, 이런 작업들을 해주는 플러그인들이 존재한다. plugins 블록 안에 필요한 플러그인들을 지정해준다.
repositories
: 저장소 정보를 관리하는 프로퍼티다. 소프트웨어를 등록하여 관리하는 장소를 가리킵니다. 로컬 환경이나 네트워크에 라이브러리를 공개하고 그 주소를 저장소로 등록하면 저장소에 있는 라이브러리를 그레이들이 취득하여 이용할 수 있다. mavenCentral() 이라는 메소드를 통해 중앙저장소를 사용할 수도 있다.
저장소는 각종 라이브러리 등이 등록된 일종의 소프트웨어 보관 장소라고 할 수 있다. 저장소에는 각종 프로그램이 등록되어 있어 그레들은 저장소로부터 필요에 따라 프로그램을 다운로드하여 이용할 수 있다.
dependencies
: 의존성에 관한 설정을 관리하는 프로퍼티다. 여기에 필요한 라이브러리등의 정보를 기술하면 그 라이브러리를 참고할 수 있다. implementation는, 컴파일 할 때 접근할 수 있는 라이브러리고, testImplementation는, 테스트를 컴파일 할 때 접근할 수 있는 라이브러리다. complieOnly는, 컴파일 시에만, runtimeOnly는 런타임시에만 사용한다는 의미다.
ext
: build.gradle 에서 사용하는 전역변수를 선언할 수 있는 블록이다. (멀티모듈일 시 주로 사용)
buildscript
: 빌드하는 동안 필요한 처리를 모아놓는 곳이다. 그러므로 Gradle이 빌드되기 전에 실행되고, 이 안에서 dependencies와 repositories가 포함될 수 있다. (멀티모듈일 시 주로 사용)
task
: task는 신입 개발자가 할 일이 없으므로 생략한다.
allprojects
는 전체 프로젝트에,subprojects
는 하위 프로젝트에, 그리고프로젝트 이름을 사용한 project
는 해당하는 프로젝트에만 동작하는 설정이다.
//settings.gradle
rootProject.name = 'sp-fastcampus-spring-sec'
["comp", "web", "server"].each {
def compDir = new File(rootDir, it)
if(!compDir.exists()){
compDir.mkdirs()
}
compDir.eachDir {subDir ->
def gradleFile = new File(subDir.absolutePath, "build.gradle")
if(!gradleFile.exists()){
gradleFile.text =
"""
dependencies {
}
""".stripIndent(20)
}
[
"src/main/java/com/sp/fc",
"src/main/resources",
"src/test/java/com/sp/fc",
"src/test/resources"
].each {srcDir->
def srcFolder = new File(subDir.absolutePath, srcDir)
if(!srcFolder.exists()){
srcFolder.mkdirs()
}
}
def projectName = ":${it}-${subDir.name}";
include projectName
project(projectName).projectDir = subDir
}
}
//build.gradle
buildscript {
ext {
spring = "2.4.1"
boot = "org.springframework.boot"
lombok = "org.projectlombok:lombok"
}
repositories {
mavenCentral()
}
dependencies {
classpath("$boot:spring-boot-gradle-plugin:$spring")
}
}
allprojects {
group = "com.sp.fc"
version = "1.0.0"
}
subprojects {
apply plugin: "java"
apply plugin: boot
apply plugin: "io.spring.dependency-management"
apply plugin: "idea"
repositories {
mavenCentral()
}
configurations {
// developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
// developmentOnly("$boot:spring-boot-devtools") //서버가 자동로그인 되는 거 막음
implementation "$boot:spring-boot-starter-security"
implementation 'com.fasterxml.jackson.core:jackson-annotations'
compileOnly lombok
testCompileOnly lombok
annotationProcessor lombok
testAnnotationProcessor lombok
testImplementation "$boot:spring-boot-starter-test"
}
test {
useJUnitPlatform()
}
}
["comp", "web"].each {
def subProjectDir = new File(projectDir, it)
subProjectDir.eachDir {dir->
def projectName = ":${it}-${dir.name}"
project(projectName){
bootJar.enabled(false)
jar.enabled(true)
}
}
}
["server"].each {
def subProjectDir = new File(projectDir, it)
subProjectDir.eachDir {dir->
def projectName = ":${it}-${dir.name}"
project(projectName){
}
}
}
help.enabled(false)
하위 모듈 생성 시,
루트모듈을 우클릭하여 생성하는 방법
과setting.gradle에 직접 타이핑하여 생성하는 방법
이 있다.
- 우클릭하여 생성하는 법 : 루트모듈(= 루트 프로젝트)에 우클릭해서 new - Module -> Gradle - Java -> Name에 하위 모듈명 작성
- 결과 (setting.gradle 파일)
//이러나 저러나 결과물은 똑같다. (gradle 새로고침 잊지마!) //rootProject.name을 통해 루트프로젝트를 생성하고, include를 통해 하위 모듈을 설정하는 거임. //그러므로 아래 내용은 tutorial 모듈이 하위 모듈들을 관리하겠다는 의미를 가진다. rootProject.name = 'tutorial' include 'core' include 'api' include 'admin' include 'consumer'
둘 다 의존성 주입이다. 그러나
Compile
는 A모듈 수정 시 A를 의존하는 모든 모듈이 rebuild되어 시간이 오래걸리는 단점이 있고,implementation
는 A모듈 수정 시 A를 직접적으로 의존하는 모듈까지만 rebuild하여 시간이 빠르다는 장점과 API 노출을 막는다는 장점이 있다.