자바 동적 에이전트 방법 및 결함
1 동적 에이전트 소개
특징: 바이트 코드 는 사용 에 따라 만 들 고 불 러 오 는 역할 을 수행 합 니 다. 원본 코드 를 수정 하지 않 는 토대 에서 방법 을 강화 합 니 다. 이 과정 에서 새로운 대상 을 만 들 것 입 니 다.분류: 인터페이스 기반 동적 에이전트, 하위 클래스 기반 동적 에이전트
2 인터페이스 기반 동적 에이전트:
:Proxy
:JDK
프 록 시 대상 을 만 드 는 요구: 프 록 시 클래스 에 의 해 최소한 하나의 인 터 페 이 스 를 실현 하고 없 으 면 사용 할 수 없 으 며, 새 대상 은 인터페이스 여야 합 니 다.프 록 시 대상 을 만 드 는 방법: Object Proxy. new Proxy Instance (ClassLoader, Class [], InvocationHandler) 방법의 인자: ClassLoader: 클래스 로 더 는 프 록 시 대상 바이트 코드 를 불 러 오 는 데 사 용 됩 니 다.프 록 시 대상 과 같은 종류의 로 더 를 사용 합 니 다.고정 표기 법.Class []: 바이트 코드 배열 은 프 록 시 대상 과 피 프 록 시 대상 이 같은 방법 을 가지 도록 하 는 데 사 용 됩 니 다.고정 표기 법.Invocation Handler: 증강 코드 를 제공 하 는 데 사용 되 는 것 은 우리 가 어떻게 대리 하 는 지 쓰 라 는 것 입 니 다.우 리 는 일반적으로 이 인터페이스의 실현 류 이 며, 일반적으로 익명 내부 류 이지 만, 필요 한 것 은 아니다.이 인터페이스의 실현 류 는 모두 누가 쓰 고 누가 쓰 는 것 입 니까?
예 를 들 어 Producer 는 피 에이전트 대상 이 고 IProducer 는 인터페이스 IProducer proxy Producer = (IProducer) Proxy. newProxyInstance (producer. getClass (). getClassLoader (), producer. getClass (). getInterfaces (), new Invocation Handler (){/ * * 역할: 피 에이전트 대상 의 모든 인터페이스 방법 을 실행 할 때 이 방법 * 방법 매개 변수의 의미 * @ param proxy 에이전트 대상 의 인용 을 거 칩 니 다. method. invoke (proxy) 를 사용 하지 마 십시오. 그러면 프로그램 이 순환 에 빠 집 니 다. invoke ()방법 이 들 어 오 는 대상 은 외부 에서 * @ param method 가 현재 실행 하 는 방법 * @ param args 현재 실행 방법 에 필요 한 매개 변수 * @ return 과 피 프 록 시 대상 방법 이 같은 반환 값 * @ throws Throwable * / @ Override public Object invoke (Object proxy, Method method, Object [] args) throws Throwable{/ / 강 화 된 코드 를 제공 합 니 다 Object returnValue = null;
//1.
Float money = (Float)args[0];
//2.
if("saleProduct".equals(method.getName())) {
returnValue = method.invoke(producer, money0.8f);
}
return returnValue;
}
});
proxyProducer.saleProduct(10000f);
3 하위 클래스 기반 동적 에이전트
제3자 패키지 에서 cglib cglib 2.1 3 과 관련 된 클래스 를 제공 합 니 다. Enhancer 공급 자: 제3자 cglib 라 이브 러 리 에서 프 록 시 대상 을 만 드 는 요구: 피 프 록 시 클래스 는 최종 클래스 에서 프 록 시 대상 을 만 드 는 방법 이 될 수 없습니다. Object Enhancer. create (Class, Callback) 방법의 매개 변수: Class: 바이트 코드 는 피 프 록 시 대상 을 지정 하 는 바이트 코드 입 니 다.
Callback: 。 。 , , 。 。
:MethodInterceptor
Producer cglibProducer = (Producer) Enhancer. create (producer. getClass (), new MethodInterceptor () {/ * * * 역할: 피 에이전트 대상 의 모든 인터페이스 방법 을 실행 할 때 이 방법 * @ param proxy 에이전트 대상 의 인용 을 거 칩 니 다. method. invoke (proxy) 를 사용 하지 마 십시오.방법 이 들 어 오 는 대상 은 외부 에서 * @ param method 현재 실행 방법 * @ param args 현재 실행 방법 에 필요 한 매개 변수 * 이상 세 개의 매개 변수 와 인터페이스 기반 동적 에이전트 에서 invoke 방법의 매개 변 수 는 같 습 니 다 * @ param methodProxy: 현재 실행 방법의 대리 대상 * @ return * @ throws Throwable * / @ Override public Object intercept(Object proxy, Method method, Object [] args, MethodProxy methodProxy) throws Throwable {/ / 증강 코드 제공 Object returnValue = null;
//1.
Float money = (Float)args[0];
//2.
if("saleProduct".equals(method.getName())) {
returnValue = method.invoke(producer, money*0.8f);
}
return returnValue;
}
}); cglibProducer.saleProduct(12000f);
결함
동적 에이전트 에 큰 결함 이 있 습 니 다. 이것 은 하위 클래스 와 인 터 페 이 스 를 기반 으로 하 는 동적 에이전트 방법 에 모두 존재 합 니 다. 다음은 인 터 페 이 스 를 기반 으로 하 는 동적 에이전트 방법 으로 예 를 들 어 1) 인 터 페 이 스 를 만 듭 니 다.
public interface Fruit {
public void eat();
public void run();
}
2) 대 리 될 클래스 만 들 기
public class Apple implements Fruit {
@Override
public void eat() {
System.out.println(" ");
}
public void run(){
System.out.println(" !!!");
eat();
}
}
3) 사 과 를 먹 기 전에 손 을 씻 고 싶 습 니 다. 달리기 전에 몸 을 풀 고 싶 습 니 다.
public class Demo1 {
@Test
public void demo1(){
final Apple apple = new Apple();
final Fruit apple1 = (Fruit)Proxy.newProxyInstance(apple.getClass().getClassLoader(), apple.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("run".equals(method.getName()))
System.out.println(" ");
if("eat".equals(method.getName()))
System.out.println(" ");
method.invoke(apple);
return null;
}
});
System.out.println("apple1 :");
apple1.run();
}
}
실행 결과
apple1 :
!!!
발견: 나 는 사 과 를 먹 기 전에 손 을 씻 지 않 았 다!증강했어
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.