dependencies 블록을 설정하는 모습을 보았을 때, 블록의 내용이 Project 객체의 dependencies 메소드로 전달됨을 알 수 있다.
예를 들어 dependencies 블록에서 implementation을 통해 라이브러리 의존성을 설정한다고 가정해보자.
그 모습이 dependencies로 전달되는 클로저에 연결된 객체의 implementation 메소드를 실행하는 것처럼 보여도, 실제로 클로저에 연결된 객체의 클래스인 DependencyHandler에는 implementation 메소드가 존재하지 않는다.
그러나 DependencyHandler와 Configuration은 서로 연관된 클래스임에는 분명하다.
DependencyHandler의 add 메소드를 통해 Configuration 객체에 의존성이 추가되기 때문이다.
여기까지 조사해본 결과 dependencies 블록에서 configuration과 동명의 메소드를 실행하는 문장이 DependencyHandler의 add를 실행하는 것과 연관되어 있음에는 분명해 보였다.
그렇다면 DependencyHandler는 어떻게 configuration과 동명의 메소드를 실행하는 것을 add를 실행하는 것으로 처리할 수 있었을까?
이를 이해하기 위해서는 그루비의 methodMissing 메소드를 알아야 한다.
methodMissing
어느 객체의 메소드를 호출할 때 메소드가 클래스 내부에 존재하지 않는다면 일반적으로는 컴파일 에러가 발생한다.
하지만 클래스에 methodMissing(String name, Object args) 메소드를 정의하고 객체를 생성한 경우라면 methodMissing이 호출되어 실행된다.
클래스에 정의되지 않은 메소드 호출에 의해 methodMissing이 호출될 때, 메소드 이름이 name으로, 인수가 args로 전달되므로 methodMissing의 정의 부분에 코드를 채울 때 메소드 이름과 인수를 활용할 수 있다.
따라서, methodMissing의 정의 부분에 add(name, args)를 호출하는 코드가 있다면 dependencies 블록에서 implementation을 함수처럼 사용해도 DependencyHandler의 add를 통해 의존성이 추가될 수 있음을 알 수 있다.
정리
결론적으로 dependencies 블록을 이용해 configuration을 추가하는 과정은 아래와 같다.
- build.gradle의 dependencies { implementation "라이브러리 정보" }를 실행한다.
- dependencies로 전달되는 클로저는 DependencyHandler 객체와 연결되어 있는 상태이다.
- 1번에서 DependencyHandler.implementation("라이브러리 정보")를 호출했으나, implementation이라는 메소드가 존재하지 않는다.
- DependencyHandler에 정의된 methodMissing이 호출된다.
- methodMissing의 인수 중 name으로 "implementation"이, args로 "라이브러리 정보"가 전달된다.
- methodMissing 내부에서 DependencyHandler의 add("implementation", "라이브러리 정보")가 실행되며 implementation에 의존성이 추가된다.
의문 해소에 도움이 되었던 글
https://stackoverflow.com/questions/57619678/how-is-dependencyhandler-add-called-in-a-build-gradle-script
https://stackoverflow.com/questions/5340189/what-is-groovys-metaclass-used-for
https://blog.mrhaki.com/2009/11/groovy-goodness-create-dynamic-methods.html
'백엔드 공부 메모 > Gradle' 카테고리의 다른 글
build.gradle 스크립트 (2) | 2024.03.18 |
---|---|
그레이들 프로젝트 빌드 과정 (3) | 2024.03.17 |
그레이들(Gradle) 소개 (0) | 2024.03.17 |