자바 에이전트 모델 및 동적 에이전트 메커니즘 깊이 분석
프 록 시 디자인 모드
에이 전 트 는 자주 사용 하 는 디자인 모델 로 다른 대상 에 게 에이 전 트 를 제공 하여 특정한 대상 에 대한 접근 을 제어 하 는 것 이 목적 이다.대리 류 는 위탁 류 의 예비 처리 메 시 지 를 여과 하고 메 시 지 를 전달 하 며 메시지 가 위탁 류 에 의 해 실 행 된 후의 후속 처 리 를 책임 집 니 다.
프 록 시 모드 의 역할 은 다른 대상 에 게 이 대상 에 대한 접근 을 제어 하기 위해 프 록 시 를 제공 하 는 것 입 니 다.어떤 경우 에 한 고객 이 다른 대상 을 직접 인용 하고 싶 지 않 거나 인용 할 수 없 으 며 대리 대상 은 클 라 이언 트 와 목표 대상 사이 에서 중개 역할 을 할 수 있다.
프 록 시 모드 에서 일반적으로 언급 되 는 역할 은 다음 과 같다.
추상 적 인 역할:실제 대상 과 대리 대상 의 공동 인 터 페 이 스 를 설명 합 니 다.
대리 역할:대리 대상 역할 내부 에 실제 대상 에 대한 인용 이 포함 되 어 있어 실제 대상 을 조작 할 수 있 고 대리 대상 은 실제 대상 과 같은 인 터 페 이 스 를 제공 합 니 다.
언제나 진실 한 대상 을 대체 할 수 있다.또한 대리 대상 은 실제 대상 조작 을 수행 할 때 다른 조작 을 추가 할 수 있어 실제 대상 을 봉인 하 는 것 과 같다.
실제 역할:대리 역할 이 대표 하 는 진실 한 대상 은 우리 가 최종 적 으로 인용 해 야 할 대상 이다.
그림 1.프 록 시 모드 도표
행위 의 일치 성 을 유지 하기 위해 대리 류 와 의뢰 류 는 보통 같은 인 터 페 이 스 를 실현 하기 때문에 방문 자 들 이 보기에 두 가 지 는 조금도 차이 가 없다.대리 류 와 같은 중간 층 을 통 해 의뢰 류 대상 에 대한 직접적인 방문 을 효과적으로 통제 할 수 있 고 의뢰 류 대상 을 잘 숨 기 고 보호 할 수 있 으 며 서로 다른 통제 전략 을 실시 하기 위해 공간 을 미리 남 겨 디자인 에 있어 더욱 큰 유연성 을 얻 었 다.자바 동적 대리 체 제 는 교묘 한 방식 으로 대리 모델 의 디자인 이념 을 완벽 하 게 실천 했다.
자바 동적 에이전트
관련 클래스 와 인터페이스
자바 동적 에이전트 의 메커니즘 을 이해 하려 면 먼저 다음 과 같은 클래스 나 인 터 페 이 스 를 알 아야 합 니 다.
・java.lang.reflect.Proxy:이것 은 자바 동적 에이전트 의 주 클래스 입 니 다.인터페이스 에 프 록 시 클래스 와 대상 을 동적 으로 생 성 하 는 정적 방법 을 제공 합 니 다.
목록 1.Proxy 의 정적 방법
// 1:
static InvocationHandler getInvocationHandler(Object proxy)
// 2:
static Class getProxyClass(ClassLoader loader, Class[] interfaces)
// 3:
static boolean isProxyClass(Class cl)
// 4: 、
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
InvocationHandler h)
java.lang.reflect.InvocationHandler:프로세서 인 터 페 이 스 를 호출 합 니 다.동적 에이전트 대상 에 집중 적 으로 처리 하 는 방법 으로 invoke 방법 을 사용자 정의 합 니 다.보통 이 방법 에서 의뢰 류 에 대한 프 록 시 접근 을 실현 합 니 다.목록 2.Invocation Handler 의 핵심 방법
// 。 ,
// 。
Object invoke(Object proxy, Method method, Object[] args)
동적 프 록 시 클래스 대상 을 만 들 때마다 이 인 터 페 이 스 를 실현 하 는 호출 프로세서 대상 을 지정 해 야 합 니 다(프 록 시 정적 방법 4 의 세 번 째 매개 변 수 를 참조).・java.lang.ClassLoader:클래스 로 더 클래스 입 니 다.클래스 의 바이트 코드 를 자바 가상 머 신(JVM)에 불 러 오고 클래스 대상 을 정의 해 야 사용 할 수 있 습 니 다.Proxy 정적 방법 으로 동적 프 록 시 클래스 를 생 성 하 는 것 도 클래스 로 더 를 통 해 불 러 와 야 사용 할 수 있 습 니 다.일반 클래스 와 의 유일한 차이 점 은 바이트 코드 가 JVM 이 실 행 될 때 동적 으로 생 성 되 는 것 이지 미리 저장 하 는 것 이 아 닙 니 다.class 파일 에 있 습 니 다.
동적 프 록 시 클래스 대상 을 생 성 할 때마다 클래스 로 더 대상 을 지정 해 야 합 니 다(프 록 시 정적 방법 4 의 첫 번 째 인자 참조)
대리 메커니즘 및 그 특징
우선 자바 동적 대 리 를 어떻게 사용 하 는 지 알 아 보 겠 습 니 다.구체 적 으로 다음 과 같은 네 가지 절차 가 있다.
1.InvocationHandler 인 터 페 이 스 를 통 해 호출 프로 세 서 를 만 듭 니 다.
2.프 록 시 클래스 에 ClassLoader 대상 과 interface 를 지정 하여 동적 프 록 시 클래스 를 만 듭 니 다.
3.반사 체 제 를 통 해 동적 에이전트 류 의 구조 함 수 를 얻 을 수 있 습 니 다.유일한 매개 변수 유형 은 프로세서 인터페이스 유형 을 호출 하 는 것 입 니 다.
4.구조 함 수 를 통 해 동적 프 록 시 클래스 인 스 턴 스 를 만 들 고 구조 시 프로세서 대상 을 매개 변수 로 호출 합 니 다.
목록 3.동적 에이전트 생 성 과정
// InvocationHandlerImpl InvocationHandler ,
// ,
InvocationHandler handler = new InvocationHandlerImpl(..);
// Proxy Interface
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });
//
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });
//
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });
실제 사용 과정 은 더욱 간단 합 니 다.Proxy 의 정적 방법 인 new Proxy Instance 는 2 단계 에서 4 단계 까지 의 과정 을 패키지 해 주 었 기 때문에 간단 한 과정 은 다음 과 같 습 니 다.목록 4.동적 에이전트 생 성 과정 간소화
// InvocationHandlerImpl InvocationHandler ,
InvocationHandler handler = new InvocationHandlerImpl(..);
// Proxy
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,
new Class[] { Interface.class },
handler );
다음은 동적 대 리 를 간단하게 실현 하 는 예 를 살 펴 보 겠 습 니 다.1.프 록 시 클래스 와 실제 클래스 인터페이스:
public interface Subject
{
public void request();
}
2.진실 클래스:
public class RealSubject implements Subject
{
public void request()
{
System.out.println("From real subject!");
}}
3.구체 적 인 대리 클래스:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler
{
private Object sub;
public DynamicSubject(Object obj)
{
this.sub = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("before calling: " + method);
method.invoke(sub, args);
System.out.println(args == null);
System.out.println("after calling: " + method);
return null;
}
주:이 프 록 시 클래스 의 내부 속성 은 Object 형식 으로 실제 사용 할 때 이 유형의 구조 방법 을 통 해 대상 에 게 전 달 됩 니 다.그 밖 에 이 종 류 는 invoke 방법 도 실현 했다.이 방법 중의 method.invoke 는 피 대리 대상 을 호출 하여 실행 할 방법 이다.방법 매개 변 수 는 sub 로 이 방법 은 sub 에 속 하고 동적 대리 류 를 통 해 우 리 는 실제 대상 을 실행 하 는 방법 전후 에 자신의 추가 방법 을 추가 할 수 있다 는 것 을 나타 낸다.4.클 라 이언 트 호출 예시:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client
{
public static void main(String[] args)
{
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSubject);
Class<?> classType = handler.getClass();
//
Subject subject = (Subject) Proxy.newProxyInstance(classType
.getClassLoader(), realSubject.getClass().getInterfaces(),
handler);
subject.request();
System.out.println(subject.getClass());
}
}
다음은 자바 동적 에이전트 프 록 시의 구조 방법 을 알 아 보 겠 습 니 다.목록 6.프 록 시 구성 방법
// Proxy , private
private Proxy() {}
// Proxy , protected
protected Proxy(InvocationHandler h) {this.h = h;}
이 어 new Proxy Instance 방법 을 빠르게 찾 아 볼 수 있 습 니 다.아주 간단 하기 때 문 입 니 다.목록 7.프 록 시 정적 방법 newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException {
// h ,
if (h == null) {
throw new NullPointerException();
}
//
Class cl = getProxyClass(loader, interfaces);
//
try {
Constructor cons = cl.getConstructor(constructorParams);
return (Object) cons.newInstance(new Object[] { h });
} catch (NoSuchMethodException e) { throw new InternalError(e.toString());
} catch (IllegalAccessException e) { throw new InternalError(e.toString());
} catch (InstantiationException e) { throw new InternalError(e.toString());
} catch (InvocationTargetException e) { throw new InternalError(e.toString());
}
}
이 를 통 해 알 수 있 듯 이 동적 에이전트 의 진정한 관건 은 getProxyClass 방법 이다.이 방법 은 인터페이스 에 프 록 시 유형 대상 을 동적 으로 생 성 하 는 것 을 책임 진다.클 라 스 대리 에 대한 필요 성 을 부정 할 수 있 는 여러 가지 이유 가 있 지만 클 라 스 동적 대 리 를 지원 하 는 것 이 더 좋 을 것 이 라 고 믿 는 이유 도 있다.인터페이스 와 클래스 의 구분 은 원래 뚜렷 하지 않 고 자바 에 가서 야 이렇게 세분 화 되 었 다.만약 에 방법의 성명 과 정 의 된 여부 만 고려 하면 두 가지 혼합 체 가 있 는데 그 이름 은 추상 류 이다.추상 류 에 대한 동적 대 리 를 실현 하 는 것 도 내재 적 가치 가 있다 고 믿는다.그 밖 에 역사 에 남 겨 진 유형 도 있 는데 그들 은 어떠한 인터페이스 도 실현 하지 못 했 기 때문에 동태 대리 와 영원히 인연 이 없 을 것 이다.이런 저런 것들 은 어 쩔 수 없 이 작은 유감 이 라 고 말 할 수 밖 에 없다.
그러나 완벽 하지 않 은 것 은 위대 하지 않 은 것 과 같 지 않다.위대 함 은 본질 이 고 자바 동적 대 리 는 좌 례 이다.
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.