CS log

TechTalk ; Gradle 본문

Spring & Spring Boot

TechTalk ; Gradle

sj.cath 2023. 9. 30. 23:52

아래 내용은 개발 동아리에서 진행한 테크 컨퍼런스 '퍼비톡'에서 Gradle에 대한 발표 내용을

바탕으로 작성하였습니다.

 

1. 목차 

오늘 발표는 빌드와 gradle 전반에 대해 소개하고 gradle을 어떻게 사용하는지 설명드리겠습니다.

 

본격적인 발표에 들어가기에 앞서, 여러분들은 gradle에 대해서 얼마나 알고 계신가요? 저는 ‘gradle 위에서 프로젝트를 빌드한다’라는 개념만 알 뿐, gradle이 무엇인지는 잘 모르고 개발을 했던 과거를 떠올리며 gradle을 주제로 발표를 하게 되었습니다. 제가 gradle에 대한 개념을 정립했던 것처럼 이 퍼비톡을 들으시는 여러분들도 gradle 전반에 대한 지식을 얻어가셨으면 좋겠습니다.

 

자, 제가 방금 전에 Gradle 위에서 빌드를 한다 라고 했습니다. 그렇다면 빌드란 무엇인지부터 살펴보겠습니다.

 

빌드란 소스코드를 컴파일, 테스트, 정적분석 등을 실행하여 실행 가능한 애플리케이션으로 만들어주는 과정입니다.

 

이렇게 빌드를 할 때 쓰이는 자바 빌드도구들은 라이브러리를 자동으로 추가 및 관리하고 동기화합니다. 즉, 시대가 변화함에 따라 등장하는 다양한 버전의 라이브러리들을 쉽게 관리하고 보안성 있게 보관할 수 있도록 도와주는 도구입니다. 비유를 하자면 우리에게 산더미 같은 과제들이 있다고 해봅시다. 이런 과제 문서들을 깔끔하게 정리할 때 바인더를 이용하는데, gradle은 이런 바인더 같은 존재인 것이죠. 용도나 순서에 따라 문서를 정리할 수 있고 음료를 쏟아도 훼손되지 않도록 보호를 해주기도 하는 유용한 존재입니다. 현재로써는 maven이나 ant가 기존에 많이 사용하던 것이어서 널리 쓰이고 있는데, gradle은 신흥강자 같은 도구입니다. 그래서 새로 프로젝트를 생성하는 개발자들은 더 효율적이고 편리한 gradle들을 사용하기 시작하고 있습니다.

 

빌드에 대한 개념을 이해했으니 본격적으로 gradle에 대해 소개를 할 수 있을 것 같습니다.

 

gradle이란 2012년에 출시된 Grovvy를 기반으로 한 오픈소스 빌드 도구로, 거의 모든 타입의 소프트웨어를 빌드할 수 있는 빌드 자동화 시스템입니다. 그리고 groovy는 JVM 상에서 실행되는 스크립트 언어입니다. JAVA와 유사한 문법 구조를 가지며, 호환성이 아주 좋다는 특징이 있습니다.

 

우리가 gradle을 사용하는 이유이자 장점에는 다음과 같은 세가지가 있는데요, 차례대로 자세하게 살펴보겠습니다.

 

먼저 프로젝트를 설정 주입 방식으로 정의하기 떄문인데요, 이는 필요한 정보가 있으면 그것을 프로젝트에 주입한다는 것을 의미합니다. 따라서 maven의 상속 구조보다 재사용에 용이합니다. 또한 프로젝트의 조건을 체크할 수 있어서 프로젝트 별로 주입되는 설정을 다르게 할 수 있습니다. 이는 groovy에 기반한 동적 빌드의 장점이기도 합니다. 아래 코드를 보았을 때에 maven의 xml보다 gradle의 groovy 형태가 훨씬 가독성이 좋은 것을 보실 수 있습니다.

 

두 번째로 멀티 프로젝트를 빌드할 수 있다는 것입니다. 이는 하나의 레포지토리 내에 여러 하위 프로젝트 구성이 가능하다는 것을 의미합니다. 그래서 만약 관리자 서버와 사용자 서버를 분리해서 진행해야될 경우, 하나의 모듈을 사용하면 관리자용과 사용자용 모두에 코드를 각각 복붙해야 합니다. 그럼 중복된 코드가 발생하겠죠. 하지만 gradle을 사용할 경우 아래 파일 구조처럼, 공통된 것 따로, 공통되지 않은 것 따로 구성할 수 있으니 훨씬 효율적입니다.

 

세 번째로는 빌드 속도가 빠르다는 것입니다. 빌드 속도가 빠를 수 있는 데에는 세가지 요소가 있습니다. 먼저 점진적 빌드입니다. Gradle은 빌드 실행 중 마지막 빌드 호출 이후에 task의 입력, 출력 혹은 구현이 변경됐는지 확인합니다. 이후 최신 상태로 간주하지 않는다면 빌드는 실행되지 않습니다. 즉, 변경되지 않은 부분은 중복 빌드를 하지 않는 것입니다.

 

두 번째로는 빌드 캐시가 존재하기 때문입니다. 빌드 캐시는 빌드 결과물을 캐시에 잠깐 담아두었다가 하나의 빌드에서 사용되는 파일들이 다른 빌드에 사용된다면 담아두었던 빌드 결과물을 다른 빌드에서 사용하는 것을 말합니다. 이 또한 처음부터 빌드를 하지 않아도 되므로 빌드 시간이 줄어들게 되는 것이죠.

 

마지막으로 데몬 프로세스입니다. 데몬 프로세스는 서비스의 요청에 응답하기 위해 오랫동안 살아있는 프로세스입니다. Gradle의 데몬 프로세스는 메모리 상의 빌드 결과물을 보관합니다. 따라서 한 번 빌드된 프로젝트는 다음 빌드에서 실행할 때 매우 적은 시간만 소요됩니다.

 

그럼 간단한 질문을 드려보겠습니다. 빌드 캐시와 데몬 프로세스의 차이는 무엇일까요? 데몬 프로세스는 Gradle 빌드 실행 후에도 메모리에 유지되어 같은 작업을 다시 실행할 때까지 계속해서 실행하는 것이고, 빌드 캐시는 이전 빌드에서 생성된 결과물을 저장하며, 같은 작업을 다시 실행할 때만 사용합니다. 아까 예시를 들었던 과제 문서로 다시 예를 들어보겠습니다. 그러니까 주머니에 문서를 가지고 있다가 필요할 때마다 꺼내 쓰는 것은 캐시, 양손에 계속 문서들을 쥐고 있으면서 필요한 문서를 내미는 것은 데몬 프로세스라고 볼 수 있겠습니다.

 

이렇게 많은 장점을 가진 gradle, 구조는 어떨까요? 모든 Gradle script는 하나 이상의 project로 구성되며, 모든 프로젝트는 하나 이상의 task로 구성되어 있습니다. 디렉토리 구조는 다음과 같이 구성이 되어 있습니다.

 

gradle을 기반으로 이제 열심히 만든 프로젝트를 빌드해볼 시간입니다. build를 하면 이 삼단계 과정을 거치게 됩니다. 먼저 초기화가 실행됩니다. 대상이 되는 프로젝트가 결정되고 각각에 대한 project 객체가 생성되는 것입니다. 그 다음으로는 프로젝트의 객체가 구성되고 구성된 task가 실행됩니다. 마지막으로 구성 단계에서 설정된 프로젝트의 테스크 중에서 실행 대상을 결정해 선택된 task가 실행됩니다.

 

그렇다면 Gradle은 어떻게 사용하는지 말씀드리겠습니다. 먼저 plugin 설정을 합니다. Plugin은 미리 구성해놓은 task들의 그룹이며, 특정 빌드 과정에 필요한 기본정보를 포함하고, 필요에 따라 정보를 수정하여 목적에 맞게 사용할 수 있습니다.

 

Plugin에는 java plugin과 war plugin이 있는데 각각 java 프로젝트, web 프로젝트를 위한 것이라고 이해하면 되겠습니다.

 

다음으로는 저장소를 설정합니다. Gradle은 Maven repository, Jcenter repository, Ivy directory 등 다양한 저장소를 지원합니다.

 

Gradle은 다양한 의존관계를 지원하는데요그 의존관계들을 알아보기 전에 의존성에 대한 기본적인 개념들을 정리해보면 다음 네 가지가 나올 수 있습니다먼저 spring 관련 의존성은 컴파일과 런타임 모두에 사용됩니다그리고 lombok은 컴파일 시에만 사용되고 h2database는 런타임시에만 사용됩니다마지막으로 spring-boot-starter-test는 테스트에서만 사용됩니다이렇게 정리한 후 이에 맞는 적당한 설정들을 해주어야 합니다.

 

이때, 제가 계속 언급했던 의존성이란 a가 b에 의존한다고 하면, a 객체가 b 객체를 사용하는 것을 의미합니다. 지금 보시는 이미지에서 화살표 방향으로 의존하고 있다는 것입니다. 여기서 내부라는 말이 있으면 b가 a에 의존할 때 제3의 객체인 c가 이를 볼 수 있다는 뜻을 덧붙일 수 있습니다. Api는 내부 의존성을 컴파일과 런타임 모두에 보이게 되고 implementation은 내부의존성을 런타임에서만 보입니다. 이때 implementation은 빌드를 api보다 최소화하였고 c가 b나 a의 수정 내용을 알 수 없기 때문에 빌드 속도가 비교적 빠릅니다.

 

compileOnly는 이름에서도 유추할 수 있듯이 compile 시에만 빌드하고 빌드 결과물에는 포함하지 않으며 RuntimeOnly는 런타임에만 사용되는 것을 말합니다. 그리고 Test라는 키워드를 앞에 붙이면 해당 의존성을 테스트 시에만 사용하도록 정의할 수 있습니다. 추가적으로 annotation을 통해 annotation processor도 명시할 수 있습니다.

 

이렇게 설정한 의존관계는 group, name, version 순으로 기술을 하고요,

 

모든 설정을 완료하고 난 후 gradle을 통해 테스트 또한 간편하게 할 수 있습니다. Gradle은 Test 시에 특정 테스트만 진행할 수 있으며 테스트의 결과를 따로 받아볼 수도 있습니다. Gradle은 테스트를 detection하고 그룹화하며 테스트 과정을 서포트합니다. 코드로는, 아래 jUnit5를 사용할 수 있습니다.

 

완성된 풀 코드는 다음과 같습니다.

 

오늘 gradle의 전반적인 지식에 대해 전달드렸는데, 더 궁금하신 점이 있다면 공식 문서를 참고하여 깊게 공부해보는 것을 추천드립니다.

발표를 위해 참고한 내용은 다음과 같습니다.

https://www.youtube.com/watch?v=ntOH2bWLWQs

https://ysiksik.github.io/elegant-tekotok/2023-02-03-LUNA-Gradle/

https://willbesoon.tistory.com/93

 

들어주셔서 감사합니다!