티스토리 뷰


오늘은 개인적으로 자바 활용의 익스퍼트 급이라고 생각하는 것 중에 하나인 BCI(Byte Code Instrumentation)에 대해서 포스팅해보고자 합니다. 저도 제가 공부하고 이해하는 선 내에서 진행해보도록 하겠습니다. 

 

자바 BCI란 뭘까? - Java BCI (Byte Code Instrumentation) #1

제가 신입시절... 자바의 리플렉션을 활용하며 그래 이것만 있으면 뭐든 다 할수 있겠는데?라고 생각하고 지냈다가 제니퍼소프트의 APM(Application Performance Monitoring) 솔루션을 만나며 마냥 신기한데? 라고 생각 했었습니다. 제니퍼소프트는 나름 국내 IT업계에서 신의 직장으로 많이 알려진 회사지요? ㅎㅎㅎ 그러다 몇년 후 EJB와 스트럿츠의 시대를 지나 스프링 프레임워크의 시대를 맞으며 AOP(Aspect Oriented Programming : 관점지향프로그래밍) 기능을 알게 됩니다.

'와 이거 기능 좋은데?'

제니퍼소프트의 제니퍼 솔루션은 자바 어플리케이션의 모니터링 솔루션입니다. 국내에서는 이쪽 분야의 선두주자이지요. 아래 화면처럼 실시간으로 서비스 성능 지표나 장애요소를 시각적으로 보여줘서 저같은 사람이 시스템을 운영하기 편하게 해줍니다.

 

image from  http://jennifersoft.com/ko/

이렇게 좋은 걸 보면서도 이건 어떻게 만들었을까?라는 호기심없이 지냈고...(일이 바쁘고 연애하기 바쁘고 놀기 바쁘고 아기 키우기 바쁘니까.)

스프링의 AOP(관점지향프로그래밍)를 만나 트랜잭션 처리나 특정 함수의 선후처리에 기능들을 넣으면서도 그냥 '오~ 이거 좋네' 하고 말았던 것입니다. 그러니 전 그저 그냥 먹고만 사는 타입인거죠.

그러다 개인 개발 프로젝트라는걸 처음 해보며 지금 말한 녀석들의 원천 기술인 BCI라는 걸 알게 되었습니다. 그러니 저도 안지는 얼마 되지 않았죠. 그러니 포스팅을 하며 자세히 공부해볼까 합니다.

이더리움이 솔리디티 언어로 작성되어 EVM(이더리움 가상 머신)에서 동작하듯 자바도 바이트코드화 된 class파일로 컴파일 되어 JVM(자바 가상 머신)에서 동작하죠. 근데 요 class파일로 컴파일 할때나 로드할 때 내가 의도한 바대로 바이트코드를 삽입할 수 있으니 이것을 Byte Code Instrumentation(Byte Code Insertion라고도...)라고 합니다. 그래서 구현할 수 있는 방법은 크게 세가지로 분류할 수 있는데 그것이.

1. Java Proxy

 

2. CGLIB

 

3. AspectJ

 

가 되겠습니다.

 

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로 컴파일 시에 클레스 파일이 실제로 변형되어있는지 확인도 해보아야겠습니다.

 

 

자바 AOP - JDK Dynamic Proxy 사용해보기 - Java AOP #2

자바 AOP JDK Dynamic Proxy를 경험해보기 위해서 테스트 클레스를 생성합니다. 지난번에 JDK Proxy에 대한 코멘트를 다음과 같이 했습니다. ​ Java Proxy같은 경우에 인터페이스를 반드시 구현해야하고

nhj12311.tistory.com

 

자바 AOP - CGLIB에 사용되는 ASM을 알아보자 - Java AOP #3

오늘은 CGLIB를 배우기 위해 ASM을 먼저 정리해봅니다. ​ 2. CGLIB는 인터페이스가 아닌 클레스를 대상으로 동작 가능하고 바이트코드를 조작해서 프록시를 만들기에 Java Proxy에 비해 성능이 좋습

nhj12311.tistory.com

 

자바 AOP - 이제 CGLIB를 사용해봅시다 - Java AOP #4

지난시간에 CGLIB를 배우기 위해 ASM을 사용해보았는데 이젠 CGLIB를 사용해봐야겠습니다. 2. CGLIB는 인터페이스가 아닌 클레스를 대상으로 동작 가능하고 바이트코드를 조작해서 프록시를 만들기

nhj12311.tistory.com

 

자바 AOP - AspectJ에 대해서 - Java AOP #5

자바의 AOP를 알아보면서 허접하게나마 각 사용방법을 훑은 것 같습니다. 최종적으로 AspectJ가 남았습니다. 이제 이놈만 정복하면 될 듯 합니다. 끝판왕이니 만큼 심혈을 기울여 조사하고 공부하

nhj12311.tistory.com


댓글
최근에 올라온 글
최근에 달린 댓글