Kotlin Reflection

권태용·2020년 10월 25일
0

Kotlin

목록 보기
1/6

이번 크롤링 엔진을 구조화 하면서 Kotlin reflection을 사용하였다. 효율적인 개발을 하려 하였으나 우선 개발을 해보자 하는 방식으로 노가다 방식의 코딩을 하였다.

여기서 노가다 방식이란 것은 모든 함수에 대한 정의를 하나씩 가져와 SpEL엔진에 등록하는 것이였다. 수동(노가다)로 등록하는 함수들의 파라미터는 이해됐지만 이를 어떻게 하면 동적으로 접근해야 할 지 몰랐다.

우선 구현을 하고 코드 피드백을 받으면서 효율적인 방식으로 수정(수정이라 하기엔 민망한 막대한 내가 짜지 않은 코드량;; ㅎㅎ)해 나갔다.

Kotlin Reflection KClass

우선 내가 등록할 함수에 대한 접근이 필요해 했다. 이때 사용한 것이 Reflection이다.

https://kotlinlang.org/docs/reference/reflection.html#reflection

Reflection은 내가 작성한 구조체를 runtime에 접근 할 수 있는 라이브러리 종류이다. 라고 설명하고 있다.

val c = MyClass::class

위와 같이 해당 클래스에 접근 할 수 있다. Class의 정보를 담는 클래스는 KClass이고 그 후에 KClass의 멤버 변수들을 통해 해당 클래스의 MemberProperty와 MemberFunction을 접근 할 수 있었다.

결과적으로

위와 같이 SpelUtil 클래스에 있는 static 함수들을 SpelContext에 동적으로 등록 할 수 있었다.

Parameter Type 비교하기

위에 SpelContext에 등록된 함수를 사용할때는 Method(param1, param2) 형식으로 호출이 가능 했다. 하지만 여러함수를 사용하다 보니 Method1(Method2(param1).Method3()) 와 같이 코드의 가독성이 낮아져서 param1.Method2().Method3().Method1()와 같은 체이닝 형식으로 변경하고자 했다.

이때 Spel엔진에 등록된 Method를 선택하는 resolver를 커스터마이즈가 가능했고 이를 활용했다. 하지만 함수의 이름과 파라미터가 일치하는지 확인하여야 했기 때문에 다시 해당 함수의 파라미터에 동적인 접근이 필요했다.

이때 Paramter에 대한 일치를 확인하기 위해서 Parameter.Type.Class 를 접근해야 했다.

KParameter

Kotlin은 함수를 KFunction클래스로 변환한다. 이때 KFunction.parameters를 확인해보면 함수의 파라미터를 다시 KParameter로 변환한다.

나는 처음에 타입을 비교할대 해당 KParameter::class로 접근 하려했다. 하지만 이는 잘 못 된 접근이다. 이는 그저 KParameter에 대한 Reflection이기에 해당 파라미터의 Type을 가져오지 못 한다.

KType

KParameter를 보면 type이라는 멤버 변수가 있다. 해단 변수의 타입을 정의하는 멤버이다. 이 멤버 변수의 Type은 KType으로 정의된다. 하지만 나는 여기서 한번더 삽질을 했다.

나는 parameter.type::class로 접근하려 했다. 하지만 결국 이는 KType에 대한 reflection을 의미한다. 내가 원하는 값은 parameter.type이 어떤 클래스로 받는지에 대한 값이다.

KType.jvmErasure

Kotlin의 제내릭 type은 모두 *로 캐스팅된다. 때문에 reified 를 사용하지 않는 이상은 Generic에 대한 클래스를 runtime에 접근이 불가능 하다. 또는 KType.jvmErasure를 통해 해당 타입의 클래스 접근이 가능하다. 'jvm에 지워진 type의 runtime class를 리턴한다' 설명을 보면 좀 더 명확하다.

Type과 Class

type과 class의 개념이 없었기에 코딩을 하면서 해매였던 부분이 있었다.객체는 클래스의 구현체이고 타입은 클래스를 지칭한다.

해당 파라미터의 타입을 가져와야 한다 생각해서 단순히 parameter.type으로 가져온다음 ::class를 하면 가져올거라 생각했다. 물론 kotlin reflection에 대한 개념이 부족해서 이런 접근을 했을 수 도 있다. 하지만 이런 개념을 구현한것이 reflection이라고 생각한다. 그렇기에 단순히 라이브러리에 대한 활용방법을 외우는 것보다 내가 어떤 개념을 코딩으로 구현하려 하는지에 대한 파악이 우선시 되어야 한다 생각된다.

profile
개발일기장

0개의 댓글