CH02 바이트 코드 분석 및 조작
Last updated
Last updated
이미 앞 챕터에서 바이트 코드가 클래스 로더에 의해서 메모리에 로드 되고, 이를 인터프리터 또는 JIT 컴파일러에 의해서 네이티브 코드로 해석되면서 실행된다는 전체 흐름을 이해했다.
이번 챕터에서는 소스 코드와 바이트 코드가 이처럼 분리되어 있다는 사실에 기반해서 바이트 코드를 조작해서 원하는 결과를 얻거나, 바이트 코드 레벨로 접근해서 필요한 분석을 할 수 있다는 것을 직접적으로 실습하고 알아보는 것이 핵심이었다.
jacoco 와 같은 라이브러리에서 사용될 수 있다. 그리고 아래에도 다시 언급하겠지만 스프링에서 컴포넌트 스캔을 위해서 바이트 코드 레벨로 분석을 한다.
프록시 객체를 만들 때 주로 사용된다. 예를 들어 JPA 에서 프록시 객체를 생성할 때 사용된다. 그 외에 AOP 에서도 사용된다.
더 자세한 사항은 강의에서 곧 프록시와 어노테이션 프로세서를 다룰 예정이므로 그 때 더 알아보도록 한다.
ASM:
Javassist:
ByteBuddy:
강의에 소개된 라이브러리들이고 강의에서는 ByteBuddy를 사용했다. 어떤 것들이 있는지를 굳이 기억해둘 필요는 없다. 하지만 ASM 이 실제로 스프링의 컴포넌트 스캔에 관여하고 있다는 것을 알게 되었다.
컴포넌트 스캔시 ClassPathScanningCandidateComponentProvider 가 관여하는데 이 때 바이트 코드 레벨로 접근하여 Bean 으로 등록할 클래스들인지를 판단한다. 즉, @Repository, @Service, @Controller, @Configuration, @Bean 과 같은 어노테이션이 있는지를 바이트 코드 레벨에서 확인하고 해당 클래스를 Bean 으로 등록해야하는지에 관해서 정보를 수집하는 것이다.
이렇게 주석에도 명확하게 써져있다.
바이트 코드 자체를 조작하는 방법과 클래스 로더가 클래스를 읽어서 메모리에 로드 할 때 바이트 코드를 조작해서 메모리에 로드 시키는 '로드 타임 위빙' 두 가지를 실습했다.
'로드 타임 위빙' 시 클래스 파일에는 변경이 생기지 않으며 클래스 로더가 메모리에 적재하기 전에 여기에 변경을 가해서 메모리에 적재하는 것이다.