Spring AOP 기초 - CGlib 동적 에이전트
CGLib 는 매우 밑바닥 에 있 는 바이트 코드 기술 을 사용 하여 하나의 클래스 에 하위 클래스 를 만 들 고 하위 클래스 에서 방법 으로 차단 하 는 기술 로 모든 부모 클래스 방법의 호출 을 차단 하고 횡 절 논리 에 따라 짜 낼 수 있다.다음은 CGLib 기술 을 사용 하여 성능 감 시 를 위 한 크로스 논리 프 록 시 대상 을 만 들 수 있 는 프 록 시 생 성 기 를 만 듭 니 다. 코드 는 다음 과 같 습 니 다.
JDK 에이전트 와 마찬가지 로 방법의 성능 을 감시 하 는 도구 클래스 가 필요 합 니 다. MethodPerformance.class
package com.cglib;
public class MethodPerformance {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformance(String serviceMethod){
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
}
public void printPerformance(){
end = System.currentTimeMillis();
long elapse = end - begin;
System.out.println(serviceMethod + " " + elapse + " ");
}
}
그리고 성능 감시 코드 를 Performance Handler 에 설치 합 니 다.package com.cglib;
public class PerformanceMonitor {
private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>();
public static void begin(String method){
System.out.println("begin monitor……");
MethodPerformance mp = new MethodPerformance(method);
performanceRecord.set(mp);
}
public static void end(){
System.out.println("end monitor……");
MethodPerformance mp = performanceRecord.get();
mp.printPerformance();
}
}
비 즈 니스 클래스 는 Forum ServiceImpl 로 JDK 에이전트 와 달리 이 곳 의 업무 방법 은 어떠한 인터페이스 도 계승 하지 않 았 습 니 다.package com.cglib;
public class ForumServiceImpl {
@SuppressWarnings("static-access")
public void removeForum(int forumId) {
System.out.println(" Forum :" + forumId);
try {
Thread.currentThread().sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@SuppressWarnings("static-access")
public void removeTopic(int topicId) {
System.out.println(" Topic :" + topicId);
try {
Thread.currentThread().sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
그리고 우 리 는 CGLib 기술 을 사용 하여 프 록 시 생 성 기 를 다음 과 같이 작성 합 니 다.package com.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
PerformanceMonitor.begin(obj.getClass().getName() + "." + method.getName());
Object result = proxy.invokeSuper(obj, args);
PerformanceMonitor.end();
return result;
}
}
마지막 으로 테스트 클래스 를 통 해 테스트:package com.cglib;
public class TestForumService {
public static void main(String[] args) {
CGLibProxy proxy = new CGLibProxy();
ForumServiceImpl forumService = (ForumServiceImpl) proxy.getProxy(ForumServiceImpl.class);
forumService.removeForum(10);
forumService.removeTopic(1023);
}
}
테스트 결 과 는 다음 과 같다.
begin monitor... 아 날로 그 포럼 기록 삭제: 10 end monitor... com. cglib. ForumServiceImpl $$$EnhancerByCGLIB $$$b80af08a. removeForum 31 밀리초 걸 려 begin monitor... 아 날로 그 삭제 Topic 기록 삭제: 1023 end monitor... com. cglib. ForumServiceImpl $$EnhancerByCGLIB $$b80af08a. removeTopic 47 밀리초 걸 립 니 다.
결과 출력 과 JDK 에이 전 트 를 사용 하 는 것 은 기본적으로 일치 하지만 클래스 이름 에 차이 가 있 습 니 다. 이 는 CGLib 가 Forum ServiceImpl 을 위 한 하위 클래스 를 실제 실행 하고 있 기 때 문 입 니 다. 위의 클래스 이름 은 만 든 하위 클래스 의 이름 입 니 다.
JDK 와 CGLib 의 비교:
JDK 동적 에이전트 가 만 든 에이전트 대상 은 JDK 1.3 에서 성능 이 좋 지 않 습 니 다.높 은 버 전의 JDK 에 서 는 동적 프 록 시 대상 의 성능 이 향상 되 었 지만 CGLib 가 만 든 동적 프 록 시 대상 의 성능 은 여전히 JDK 가 만 든 프 록 시 대상 의 성능 보다 훨씬 높다 (약 10 배).그러나 CGLib 는 프 록 시 대상 을 만 드 는 데 걸 리 는 시간 이 JDK 동적 에이전트 (약 8 배) 보다 많 기 때문에 Singleton 의 프 록 시 대상 이나 인 스 턴 스 풀 이 있 는 프 록 시 에 대해 서 는 프 록 시 대상 을 자주 만 들 필요 가 없 기 때문에 CGLib 동적 프 록 시 기술 을 사용 하 는 것 이 좋 고 반대로 JDK 동적 프 록 시 기술 을 적용 합 니 다.단, CGLib 는 하위 클래스 를 동적 으로 생 성 하 는 방식 으로 프 록 시 대상 을 생 성하 기 때문에 대상 클래스 의 final 방법 에 대해 프 록 시 를 할 수 없습니다. 또한 클래스 가 어떠한 인터페이스 도 실현 되 지 않 으 면 CGLib 를 선택 하여 동적 프 록 시 를 할 수 밖 에 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.