• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

CGLIB 와 클래스 로딩시점의 차이..

24.04.16 11:51 작성 조회수 73

0

동적 프록시로 앞에서 배운 CGLIB도

바이트 코드를 조작하는거 아닌가요?

그런데 CGLIB도 프록시를 사용하는것이자나요?

 

AOP에서 AspectJ의 클래스로딩시점에 바이트 코드을 조작한다는건 무슨차이인가요? 여기서는 프록시를 사용안하고 바이트 코드만 조작한다는거고

cglib는 바이트 코드도 조작하고 프록시도 사용하나요..?

그런거라면.. 바이트 코드를 어차피 조작할건데 cglib는 왜 프록시를 사용하나요?ㅠㅠ

 

답변 1

답변을 작성해보세요.

2

안녕하세요. 리어스리님

CGLIB와 AspectJ에 대해 혼동이 있으신 것 같습니다. 먼저, 이 두 기술은 Java에서 AOP(Aspect-Oriented Programming)를 구현하기 위한 다른 접근 방식을 제공합니다. 두 기술 모두 바이트 코드 조작을 통해 작동하지만, 그 방식과 적용 시점에 차이가 있습니다.

CGLIB

CGLIB (Code Generation Library)는 런타임에 프록시를 생성하여 바이트 코드를 조작합니다. CGLIB는 주로 타겟 객체의 서브 클래스를 동적으로 생성하고, 이를 통해 메서드 호출을 가로채 AOP를 구현합니다. 이렇게 생성된 서브 클래스는 원래 클래스의 프록시 역할을 하며, AOP의 관점에서 원하는 기능(로깅, 트랜잭션 관리 등)을 추가할 수 있습니다.

CGLIB가 프록시를 사용하는 이유는 바이트 코드 조작 자체만으로는 원본 객체의 행동을 변경하거나 확장하기 어렵기 때문입니다. 프록시를 통해 원본 객체를 감싸고, 이 프록시에서 추가적인 기능을 실행한 후 실제 객체의 메서드를 호출하게 되므로, 사용자는 원본 객체를 수정하지 않고도 원하는 기능을 적용할 수 있습니다.

AspectJ

AspectJ는 컴파일 시간(또는 클래스 로딩 시간)에 바이트 코드를 조작합니다. AspectJ는 특히 더 강력한 AOP 기능을 제공하며, 이는 컴파일 시점에 소스 코드 또는 클래스 파일에 직접적인 바이트 코드 조작을 통해 이루어집니다. AspectJ는 프록시를 사용하지 않고 바로 바이트 코드를 조작하여, 원하는 AOP 기능을 클래스에 직접 삽입합니다. 이로 인해 실행 시에 추가적인 객체 생성이나 호출이 필요 없으며, 성능상의 이점을 가질 수 있습니다.

CGLIB와 AspectJ의 차이점

  • 조작 시점: CGLIB는 런타임에, AspectJ는 컴파일 시간 또는 클래스 로딩 시에 조작합니다.

  • 프록시 사용: CGLIB는 프록시를 사용하여 메서드 호출을 가로챈다. AspectJ는 프록시 없이 직접 클래스의 바이트 코드를 변경합니다.

  • 성능: AspectJ는 컴파일 시간에 바이트 코드를 조작하기 때문에, 런타임에 성능 이점을 가질 수 있습니다. 반면, CGLIB는 런타임에 프록시 객체를 생성하므로, 이에 따른 오버헤드가 발생할 수 있습니다.

바이트 코드를 조작하는 기술을 사용하더라도, CGLIB가 프록시를 사용하는 이유는 런타임에 유연성을 제공하고, 원본 코드를 변경하지 않고도 동적으로 기능을 추가할 수 있기 때문입니다. (실무에서 AspectJ를 적용하려면 여러가지 제약이 있기 때문에 사실 도입이 쉽지 않습니다. 대신에 CGLIB는 바로 도입할 수 있습니다.)

감사합니다.

친절한 답변 너무감사드립니다. 궁금한점 다시 여쭈어봅니다ㅠ

결국 CGLIB는 런타임시점(스프링에 프록시로 빈을 등록하는 그 시점!)에 프록시 객체를 생성하는데

 

정확히 바이트 코드를 조작한다는곳이 어디인지 궁금합니다..

 

차이점은 CGLIB는 결국 프록시를 생성하는건데

프록시 생성부터 모든걸 바이트코드를 조작한다는건지?

아니면 프록시를 생성후 , 프록시 객체의 모든 코드를 전부 바이트코드를 조작해서 만드는건가요?

아니면 아래 부분에서 부가기능과 실제 대상 호출 부분만 조작하는건가요?

image아니면 실제 대상 호출부분 하나만 바이트 코드로 조작을 해서 심어주는건가요?ㅠㅠ

 

아래는 GPT의 답변인데 애매합니다 ㅠ

"CGLIB는 대상 객체의 클래스 파일을 로드하고, 해당 클래스를 상속한 새로운 서브 클래스를 생성합니다. 이 새로운 서브 클래스는 대상 객체의 모든 메소드를 오버라이드하고, 각 메소드 호출 전후에 어드바이스 코드를 삽입합니다. 이 과정에서 CGLIB은 ASM(Java bytecode manipulation framework)이라는 라이브러리를 사용하여 바이트 코드를 직접 생성 및 수정"

 

안녕하세요. 리어스리님

CGLIB는 바이트 코드 조작을 통해서 프록시 클래스를 만드는 역할을 합니다. 프록시 클래스는 기존에 없던 코드(클래스)이기 때문에 이 코드를 바이트 코드 조작으로 만드는 것입니다. 쉽게 이야기해서 프록시 클래스라는 것이 없기 때문에 이 클래스를 CGLIB가 바이트 코드 조작을 통해서 만들어냅니다.

참고로 CGLIB는 개발자가 작성한 코드를 조작하지는 않습니다.

개발자가 작성한 클래스를 직접 조작하는 것은 AspectJ가 합니다.

감사합니다.