오늘은 개인적으로 자바 활용의 익스퍼트 급이라고 생각하는 것 중에 하나인 BCI(Byte Code Instrumentation)에 대해서 포스팅해보고자 합니다. 저도 제가 공부하고 이해하는 선 내에서 진행해보도록 하겠습니다.
제가 신입시절... 자바의 리플렉션을 활용하며 그래 이것만 있으면 뭐든 다 할수 있겠는데?라고 생각하고 지냈다가 제니퍼소프트의 APM(Application Performance Monitoring) 솔루션을 만나며 마냥 신기한데? 라고 생각 했었습니다. 제니퍼소프트는 나름 국내 IT업계에서 신의 직장으로 많이 알려진 회사지요? ㅎㅎㅎ 그러다 몇년 후 EJB와 스트럿츠의 시대를 지나 스프링 프레임워크의 시대를 맞으며 AOP(Aspect Oriented Programming : 관점지향프로그래밍) 기능을 알게 됩니다.
'와 이거 기능 좋은데?'
제니퍼소프트의 제니퍼 솔루션은 자바 어플리케이션의 모니터링 솔루션입니다. 국내에서는 이쪽 분야의 선두주자이지요. 아래 화면처럼 실시간으로 서비스 성능 지표나 장애요소를 시각적으로 보여줘서 저같은 사람이 시스템을 운영하기 편하게 해줍니다.
이렇게 좋은 걸 보면서도 이건 어떻게 만들었을까?라는 호기심없이 지냈고...(일이 바쁘고 연애하기 바쁘고 놀기 바쁘고 아기 키우기 바쁘니까.)
스프링의 AOP(관점지향프로그래밍)를 만나 트랜잭션 처리나 특정 함수의 선후처리에 기능들을 넣으면서도 그냥 '오~ 이거 좋네' 하고 말았던 것입니다. 그러니 전 그저 그냥 먹고만 사는 타입인거죠.
그러다 개인 개발 프로젝트라는걸 처음 해보며 지금 말한 녀석들의 원천 기술인 BCI라는 걸 알게 되었습니다. 그러니 저도 안지는 얼마 되지 않았죠. 그러니 포스팅을 하며 자세히 공부해볼까 합니다.
이더리움이 솔리디티 언어로 작성되어 EVM(이더리움 가상 머신)에서 동작하듯 자바도 바이트코드화 된 class파일로 컴파일 되어 JVM(자바 가상 머신)에서 동작하죠. 근데 요 class파일로 컴파일 할때나 로드할 때 내가 의도한 바대로 바이트코드를 삽입할 수 있으니 이것을 Byte Code Instrumentation(Byte Code Insertion라고도...)라고 합니다. 그래서 구현할 수 있는 방법은 크게 세가지로 분류할 수 있는데 그것이.
가 되겠습니다.
1. Java Proxy같은 경우에 인터페이스를 반드시 구현해야하고 리플렉션을 사용하여 구현한 기술이기에 상대적으로 퍼포먼스가 떨어지는 특징을 갖습니다. 인터페이스를 극혐하는 저와 퍼포먼스가 떨어지는것도 싫어하는 저에게는 일단 탈락.
2. CGLIB는 인터페이스가 아닌 클레스를 대상으로 동작 가능하고 바이트코드를 조작해서 프록시를 만들기에 Java Proxy에 비해 성능이 좋습니다. 일반적으로 스프링 프레임워크에서 AOP 기능을 사용하게 된다면 CGLIB를 사용하게 되지 않을까 싶습니다만...
3. Aspectj는 영포자인 나에게 위빙(Weaving)이라는 와닿지 않는 표현을 써서 당황케 했습니다.
머 암튼 aspect 지향 프로그래밍의 구현이랄 수 있는데 AJC(AspectJ용 컴파일러)로 컴파일 시에 바이트코드를 직접적으로 넣을 수 있는 CTW( Compile Time Weaving)방식을 사용할 수 있고 직접적으로 클레스 파일에 수정을 가하는 방식이기 때문에 가장 속도가 빠를수밖에 없다고 합니다. 물론 LTW(Load Time Weaving)방식을 선택해서 사용할 수 있지만 굳이 쓸 이유가 없어보입니다.
저같은 경우 제가 운영하는 일부 사이트에도 CTW 방식으로 해서 초기 구축 시에 적용을 해놓았습니다.
Java Proxy와 CGLIB는 프록시 방식이기에 함수처리만 가능한 반면 aspectJ는 함수와 예외 처리 등 다양한 처리가 가능한 완전체같은 존재라서 선택했습니다. 물론 통상적으로 쓰이는 공통 로그, 트랜잭션 처리와 같이 CGLIB 방식으로도 충분하다면 CGLIB도 충분히 훌륭하게 활용 가능한 방법이라고 생각합니다.
따라서 진짜 BCI라는 표현을 쓰려면 여기선 AspectJ를 말하는 것이겠죠? 정식으로 지원하기 전의 1.4버전까지는 어둠의 자식으로 불렸다고 하고 1.5버전부터 정식지원했다고도 하네요. ( 이런 좋은 걸 왜... )
다음편 부터는 세가지 방식에 대해 더 디테일하게 구현도 해보고 소스와 동작 레벨에서 파보고 aspectJ로 컴파일 시에 클레스 파일이 실제로 변형되어있는지 확인도 해보아야겠습니다.
'dev > java' 카테고리의 다른 글
자바(JDK, JRE) 모든 버전 다운로드( 6,7,8,9,10,11,12,13,14,15, 16, 17,18,19,20,21) (8) | 2024.01.01 |
---|---|
Java, 안드로이드 PKIX path building failed 에러 원인 및 해결 방법 (1) | 2022.05.10 |
Java Unknown Source 이유, 원인 (0) | 2021.11.17 |
자바(JDK, JRE) 쉽고 빠른 설치, 환경 설정 방법 (1) | 2021.08.10 |
자바 해시 테이블( Hashtable), 해시 맵(HashMap) 구조와 원리 (1) | 2021.07.10 |
자바 AOP - AspectJ에 대해서 - Java AOP #5 (0) | 2021.02.16 |
자바 AOP - 이제 CGLIB를 사용해봅시다 - Java AOP #4 (0) | 2021.02.16 |
자바 AOP - CGLIB에 사용되는 ASM을 알아보자 - Java AOP #3 (0) | 2021.02.16 |