에이전트 모드 의 jdk 동적 에이전트 구현

4178 단어 디자인 모드
동적 대 리 를 배우 기 전에 정적 대 리 를 이해 하고 정적 대리 의 단점 을 명심 해 야 한다.
//               
public interface ProxyInterface {
    public void say(String str);
}

//                     
public class ProxyImpl implements ProxyInterface {
    @Override
    public void say(String str) {
        System.out.println("ProxyImpl.say is " +str);
    }
}

//      
public class ProxyClass implements InvocationHandler {
    Object o;
    public void setTarget(Object o){
        this.o = o;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("            ");   
        method.invoke(o,args);
        System.out.println("            ");
        return null;
    }
}

//  
//    jdk    
    public static void main(String[] args) {
        ProxyInterface proxyInterface = new ProxyImpl();
        ProxyClass proxyClass = new ProxyClass();
        proxyClass.setTarget(proxyInterface);
	//                           
        ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(proxyInterface.getClass().getClassLoader(),proxyInterface.getClass().getInterfaces(),proxyClass);
        System.out.println("------------------------------------------");
        proxy.say("hello");

        System.out.println(proxy.getClass().getName());
        System.out.println(proxyInterface.getClass().getName());
    }


결과: D: \ developmenttool\jdk1.8.0_181\bin\java.exe
호출 방법 전에 실행 되 는 방법 ProxyImpl. say is hello 가 호출 방법 후에 실행 되 는 동작 com. sun. proxy. $Proxy 0 / / 이것 은 jdk 에서 생 성 된 에이전트 클래스 com. test. Proxy. ProxyImpl / / / 이것 은 에이전트 클래스 입 니 다.
Process finished with exit code 0
설명: 프 록 시 클래스 ProxyClass 는 인터페이스 Invocation Handler 를 실현 하고 그 안의 방법 을 다시 써 야 합 니 다 @ Override Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {System. out. println ("호출 방법 전에 실행 하 는 방법"), method. invoke (o, args), System. out. println ("호출 방법 후에 실행 하 는 작업"), return null;}
그 중에서 method. invoke (o, args);첫 번 째 매개 변 수 를 제외 하고 나머지 는 고정 쓰기 입 니 다. 첫 번 째 매개 변 수 는 우리 가 대리 해 야 할 실현 류 가 method. invoke (o, args) 에 있 습 니 다.이전에 우리 가 추가 한 방법 이나 코드 는 대리 되 는 방법 전에 method. invoke (o, args) 에서 실 행 됩 니 다.그 다음 에 저희 가 추가 한 방법 이나 코드 는 대리 되 는 방법 후에 실 행 됩 니 다.
동적 대 리 는 정적 대리 의 단점 을 해결 하기 위해 탄생 한 것 이기 때문에 우 리 는 동적 대리 와 정적 대리 의 차이 점 을 알 아야 한다. 동적 대 리 는 우리 가 직접 대리 류 를 쓸 필요 가 없다. 상기 프 록 시 클래스 는 우리 가 대리 류 라 고 말 하 는 것 은 쓰기 방법 이 다 르 기 때문에 프 록 시 클래스 를 쓰 지 않 는 다 고 가정 하기 때문이다. 우 리 는 이렇게 동적 대 리 를 실현 할 수 있다.
    public static void main(String[] args) {
        ProxyInterface proxyInterface = new ProxyImpl();
        ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(
        	proxyInterface.getClass().getClassLoader(), 
       	 	proxyInterface.getClass().getInterfaces(), 
       	 	new InvocationHandler() {
            	@Override
            	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                	System.out.println("    ");
               		 method.invoke(proxyInterface,args);
                	System.out.println("    ");
                	return null;
           		 }
       	 });

        proxy.say("     ");

    }
//  
    
ProxyImpl.say is      
    

Process finished with exit code 0


첫 번 째 쓰 기 는 Invocation Handler 인터페이스의 실현 을 쓰 는 것 에 불과 하 다. 두 번 째 는 사용 할 때 Invocation Handler 인 터 페 이 스 를 실현 하 는 것 이다. 아무리 써 도 우 리 는 첫 번 째 쓰 기 를 예 로 들 면 두 가 지 를 발견 할 수 있다.
  • 우리 의 대 리 는 구체 적 인 어느 인터페이스 와 무관 하 다. 우 리 는 우리 가 대리 의 실현 류 를 실현 하려 면 전달 하면 된다
  • 만약 에 인터페이스 가 바 뀌 면 우리 의 대리 류 는 어떠한 변동 도 할 필요 가 없다. 상기 두 가 지 를 알 면 우 리 는 왜 동태 대 리 를 제출 하 는 지 알 수 있다.
  • 우리 의 프 록 시 클래스 는 실제 jdk 에서 컴 파일 하 는 동안 동적 으로 생 성 된 것 입 니 다. 다시 말 하면 우리 의 jdk 는 컴 파일 할 때 proxy Interface. getClass (). getInterfaces () 라 는 인터페이스 동태 에 따라 그의 실현 클래스 를 만 들 었 습 니 다. 컴 파일 할 때 만 생 성 된 실제 클래스 이기 때문에 인 터 페 이 스 는 반드시 바 뀌 지 않 을 것 입 니 다. 동시에 대 리 를 실현 할 때 전달 은 대리 류, 실현 이 필요 합 니 다.인터페이스 와 상 관 없 이 모든 인터페이스 에 프 록 시 클래스 를 쓸 필요 가 없습니다.
    요약 하면 동적 에이전트 가 정적 대 리 를 미리 작성 하 는 절 차 를 jdk 에 게 맡 겨 컴 파일 할 때 생 성 되 기 때문에 정적 에이전트 의 단점 을 피 할 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기