자바 동적 에이전트 (전재)
doc 문 서 를 보면 자바. lang. reflect 패키지 에 Proxy 라 는 클래스 가 있 습 니 다.다음은 doc 문서 가 Proxy 클래스 에 대한 설명 입 니 다.
"A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object, which implements the interface
InvocationHandler
." 프 록 시 클래스 의 디자인 은 프 록 시 모드 의 디자인 사상 을 사용 하고 프 록 시 클래스 대상 은 프 록 시 목표 의 모든 인 터 페 이 스 를 실현 하 며 목표 대상 을 대체 하여 실제 작업 을 한다.그러나 이런 대 체 는 간단 한 대체 가 아니 라 아무런 의미 가 없다. 대리 의 목적 은 목표 대상 방법 을 바탕 으로 강화 하 는 것 이다. 이런 강화 의 본질은 보통 목표 대상 의 방법 을 차단 하 는 것 이다.따라서 프 록 시 는 차단 방법 이 호출 될 때 어떤 처 리 를 하 는 지 알려 주 는 방법 차단 기 를 포함해 야 한다.Invocation Handler 는 바로 차단기 의 인터페이스 이다.
Invocation Handler 인터페이스 도 java. lang. reflec 에 있 습 니 다.
Object invoke ( Object proxy, Method method, Object [] args)
이 인 터 페 이 스 는 세 개의 매개 변수 가 있 는데 그 중에서 두 번 째 와 세 번 째 매개 변 수 는 모두 이해 하기 쉽다. 하 나 는 차단 되 는 방법 이 고 하 나 는 이 방법의 매개 변수 목록 이다.관건 은 첫 번 째 매개 변수 다.doc 문서 의 해석 에 따라
proxy - the proxy instance that the method was invoked on
즉, proxy 는 프 록 시 인 스 턴 스 여야 하 는데 왜 이 인 자 를 입력 해 야 합 니까?
이 문 제 를 가지 고 스스로 작은 프로그램 을 만들어 약간의 실험 을 하 였 다.
///////////////////////////////////////
public interface IAnimal { void info(); }
////////////////////////////////////
public class Dog implements IAnimal
{
public void info() { System.out.println("I am a dog!"); } }
/////////////////////////////////////// import java.lang.reflect.*;
public class ProxyTest { public static void main(String[] args) throws InterruptedException { final IAnimal animal = new Dog(); Object proxyObj =Proxy.newProxyInstance( animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) { try { System. out. println ("차단 되 는 방법:" + method. getName ()); return method.invoke(animal, args); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }); if(proxyObj instanceof IAnimal) { System.out.println("the proxyObj is an animal!"); } else { System.out.println("the proxyObj isn't an animal!"); } if(proxyObj instanceof Dog) { System.out.println("the proxyObj is a dog!"); } else { System.out.println("the proxyObj isn't a dog!"); } IAnimal animalProxy = (IAnimal)proxyObj; animalProxy.info(); animalProxy.hashCode(); System.out.println(animalProxy.getClass().getName().toString()); } }
프로그램 실행 결 과 는 다음 과 같 습 니 다.
the proxyObj is an animal! the proxyObj isn 't a dog! 차단 되 는 방법: info I am a dog! 차단 되 는 방법: hashCode $Proxy 0
결 과 를 보면 다음 과 같은 몇 가 지 를 알 수 있다.
1. proxy Obj 는 목표 대상 인 터 페 이 스 를 실현 하 는 대상 이지 목표 대상 과 다르다. 즉, 이러한 대리 체 제 는 인 터 페 이 스 를 대상 으로 하 는 것 이지 유형 을 대상 으로 하 는 것 이 아니다.
2. info 방법 (인터페이스 에서) 이 성공 적 으로 차단 되 었 습 니 다. hashCode 방법 도 성공 적 으로 차단 되 었 습 니 다. 그러나 의외로 getClass 방법 (Object 류 를 계승 하 는 방법) 은 차단 되 지 않 았 습 니 다!
3. 디 버 깅 을 사용 하면 Invocation 인터페이스 에서 invoke 방법 으로 들 어 오 는 proxy 매개 변 수 는 프 록 시 대상 인 스 턴 스 proxy Obj 임 을 알 수 있 습 니 다.
왜 getClass () 가 차단 되 지 않 았 습 니까? proxy 인 자 는 무슨 소 용이 있 습 니까?
우선, 시험 해 보 세 요. 이 proxy 매개 변 수 는 프 록 시 인 스 턴 스 대상 이 므 로 당연히 proxy Obj 와 같 습 니 다. info 등 방법 을 호출 할 수 있 습 니 다. 따라서 invoke 방법 에 다음 과 같은 문 구 를 추가 할 수 있 습 니 다.
((IAnimal)proxy).info();
결 과 는:
the proxyObj is an animal! the proxyObj isn 't a dog! 차단 되 는 방법: info 차단 되 는 방법: info
.......
차단 방법: info 차단 방법: info
그 다음 에 창고 가 넘 쳐 요.
결 과 는 분명 합 니 다. invoke 방법 에서 proxy 를 호출 하 는 방법 은 다시 invoke 방법 을 일 으 킬 수 있 습 니 다. 이것 은 순환 에 빠 졌 습 니 다. 최종 결 과 는 당연히 스 택 이 넘 쳤 습 니 다.
invoke 방법 에서 proxy. getClass () 를 호출 할 수 있 습 니 다. 프로그램 은 정상적으로 실 행 될 수 있 습 니 다. 그러나 hashCode () 방법 을 호출 하면 스 택 이 넘 칠 수 있 습 니 다.
위의 시험 을 통 해 invoke 인터페이스 에 있 는 proxy 인 자 는 실 현 된 인 터 페 이 스 를 호출 하 는 방법 에 사용 할 수 없다 는 초보적인 결론 을 얻 을 수 있 습 니 다. 이상 한 것 은 hashCode () 와 getClass () 방법 은 모두 Object 에서 계승 하 는 방법 입 니 다. 왜 하 나 는 다른 것 으로 할 수 있 습 니까? 첫 번 째 의문 을 가지 고 doc 문서 에 가서 Object 의 이 두 가지 방법 을 살 펴 보 니 getClass () 를 발견 하 였 습 니 다.final 로 정의 되 어 있 습 니 다. hashCode () 는 아 닙 니 다. 이 때 문 입 니까? equals 가 시도 하면 스 택 이 넘 칠 수 있 습 니 다. wait () 와 같은 다른 final 방법 을 찾 아 보 았 습 니 다. invoke 는 차단 하지 않 았 습 니 다. final 이 관건 입 니까?
또 하나의 문 제 는 proxy 가 무슨 소 용이 있 습 니까? proxy 가 getClass () 를 호출 할 수 있 으 니방법, 우 리 는 proxy 의 Class 클래스 이미 지 를 얻 을 수 있 습 니 다. 예 를 들 어 proxy 프 록 시 인 스 턴 스 에 관 한 모든 종류의 정 보 를 얻 을 수 있 습 니 다. 예 를 들 어 방법 목록, Annotation 등 은 우리 에 게 proxy 를 분석 하 는 유력 한 도구 입 니 다. 예 를 들 어 Annotation 분석 방법 을 분석 하 는 성명 식 사무 수 요 를 통 해 proxy 인 자 를 전달 하 는 것 이 이러한 의도 라 고 생각 합 니 다.
Invocation Handler 의 자료
패키지: java. lang. reflect
public interface InvocationHandler
InvocationHandler
프 록 시 인 스 턴 스 호출 처리 프로그램 이 실현 하 는 인터페이스 입 니 다.모든 코드 인 스 턴 스 는 하나의 호출 처리 프로그램 을 가지 고 있 습 니 다. 프 록 시 인 스 턴 스 호출 방법 을 사용 할 때 방법 호출 을 인 코딩 하고 호출 처리 프로그램
invoke
에 할당 합 니 다.다음 버 전부터:
JDK1.3
invoke
Object
invoke
(Object
proxy,
Method
method,
Object
[] args)
throws Throwable
프 록 시 인 스 턴 스 에서 방법 을 호출 하고 결 과 를 되 돌려 줍 니 다. 방법 과 연 결 된 프 록 시 인 스 턴 스 에서 방법 을 호출 할 때 호출 처리 프로그램 에서 이 방법 을 호출 합 니 다.
인자:
proxy
- 그 위 에서 호출 하 는 방법의 에이전트 인 스 턴 스method
- 프 록 시 인 스 턴 스 에서 호출 되 는 인터페이스 방법 에 대응 하 는Method
실례.Method
대상 의 성명 류 는 그 중에서 성명 방법의 인터페이스 가 될 것 이다. 이 인 터 페 이 스 는 대리 류 가 계승 방법 을 가 진 대리 인터페이스의 초 인터페이스 일 수 있다.args
- 프 록 시 인 스 턴 스 에 호출 되 는 매개 변수 값 을 포함 하 는 대상 배열 입 니 다. 인터페이스 방법 이 파 라 메 터 를 사용 하지 않 으 면...null
. 기본 유형의 매개 변 수 는 적당 한 기본 포장 기 류 에 포장 된다 (예 를 들 어java.lang.Integer
또는java.lang.Boolean
의 실례 중.돌아 가기:
프 록 시 인 스 턴 스 의 방법 에서 되 돌아 오 는 값 을 호출 합 니 다. 인터페이스 방법의 성명 반환 형식 이 기본 형식 이 라면 이 방법 이 되 돌아 오 는 값 은 기본 포장 대상 클래스 의 인 스 턴 스 입 니 다. 그렇지 않 으 면 설명 반환 형식 으로 분 배 될 수 있 습 니 다. 이 방법 이 되 돌아 오 는 값 은 다음 과 같 습 니 다.
null
또한 인터페이스 방법의 반환 유형 은 기본 유형 이 고 대리 인 스 턴 스 의 방법 호출 은 던 집 니 다.NullPointerException
. 그렇지 않 으 면 이 방법 이 되 돌아 오 는 값 이 상기 인터페이스 방법의 성명 반환 형식 과 호 환 되 지 않 으 면 프 록 시 인 스 턴 스 의 방법 호출 을 던 집 니 다.ClassCastException
。 던 지기:
Throwable
- 프 록 시 인 스 턴 스 의 방법 에서 던 진 이상 을 호출 합 니 다. 이 이상 한 유형 은 인터페이스 방법 에 할당 할 수 있어 야 합 니 다.throws
자구 에 명 시 된 이상 유형 이나 검사 되 지 않 은 이상 유형java.lang.RuntimeException
또는java.lang.Error
. 이 방법 이 검 사 를 거 친 이상 을 던 지면 인터페이스 방법 에 할당 할 수 없습니다.throws
자구 에서 설명 한 모든 이상 유형, 에이전트 인 스 턴 스 방법 호출 은 이 방법 을 포함 하여 던 진 이상 한 것 을 던 집 니 다.UndeclaredThrowableException
。
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.