Proxy 대리자 모드 (2)

3755 단어

1. JDK의 동적 에이전트는 하나의 인터페이스와 하나의 클래스가 있다


InvocationHandler 커넥터
package java.lang.reflect;

public interface InvocationHandler {

public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
}
  • 매개 변수 설명: Object proxy: 프록시된 개체 Method method: 호출할 방법 Object[] args: 메소드 호출에 필요한 매개 변수
  • InvocationHandler 인터페이스의 하위 클래스를 에이전트의 최종 작업 클래스로 생각하고 $Proxy1을 대체할 수 있습니다.
    Proxy 클래스: Proxy 클래스는 프록시를 전문적으로 완성하는 조작 클래스로 한 개 이상의 인터페이스를 통해 실현 클래스를 동적으로 생성할 수 있으며 다음과 같은 조작 방법을 제공한다.
    public static Object newProxyInstance(ClassLoader loader,
                                      Class>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
     {...}
    
  • 매개 변수 설명:
  • ClassLoader loader: 클래스 로더Class>[]interfaces: 모든 인터페이스를 얻는 InvocationHandler h: InvocationHandler 인터페이스를 받는 하위 클래스 실례 Ps: 클래스 로더는Proxy 클래스의 newProxyInstance () 방법에서 클래스 로더 클래스의 실례가 필요합니다. 클래스 로더는 실제적으로 클래스 로더에 대응하고 자바에는 주로 세 종류의 로더가 있습니다.(1)Boostststrap ClassLoader: 이 로더기는 C++로 작성되어 일반 개발에서는 볼 수 없습니다.(2) Extendsion ClassLoader: 확장 클래스를 불러오는 데 사용되며 일반적으로 jre\lib\ext 디렉터리의 클래스에 대응합니다.(3) AppClassLoader: (기본값) classpath에서 지정한 클래스를 불러옵니다. 가장 자주 사용하는 것은 마운트기입니다.

    2. JDK 동적 에이전트 구현


    정적 프록시 클래스와 대조되는 것은 동적 프록시 클래스입니다. 동적 프록시 클래스의 바이트 코드는 프로그램이 실행될 때 자바 반사 메커니즘에 의해 동적으로 생성되며, 프로그램이 직접 원본 코드를 작성할 필요가 없습니다.동적 프록시 클래스는 프로그래밍 작업을 간소화할 뿐만 아니라 소프트웨어 시스템의 확장성을 향상시켰다. 왜냐하면 자바 반사 메커니즘은 임의의 유형의 동적 프록시 클래스를 생성할 수 있기 때문이다.java.lang.reflect 패키지의 Proxy 클래스와 InvocationHandler 인터페이스는 동적 프록시 클래스를 생성하는 능력을 제공합니다.

    1. RunAble 인터페이스


    우리는 RunAble의 모든 실현 클래스의Proxy를 생성하고 인터페이스를 먼저 정의하려고 합니다
    package com.mmb.jdk;
    
    public interface RunAble {
    public void running();
    }
    

    2. RunAble의 프록시 클래스를 정의하는 RunAbleProxy

    package com.mmb.jdk;
    
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class RunAbleProxy implements InvocationHandler {
    private Object target;
    
    public Object bind(Object target)
    {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        //   // ( ,cglib )
    }
    
    //     invoke 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("$Proxy is ready to run.");
        result = method.invoke(target,args);
        System.out.println("$Proxy had done.");
        return result;
    }
    }
    

    3. RunAble 인터페이스의 실현 유형

    package com.mmb.jdk;
    public class Car implements RunAble {
    @Override
    public void running() {
        System.out.println("Car is running");
    }
    }
    
    package com.mmb.jdk;
    
    public class Dog implements RunAble {
    @Override
    public void running() {
        System.out.println("Dog is running");
    }
    }
    

    4. 테스트 클래스 ProxyStudy

    package com.mmb.jdk;
    
    public class ProxyStudy
    {
    public static void main(String[] args) {
        RunAbleProxy runAbleProxy = new RunAbleProxy();
        RunAble runAble = (RunAble)runAbleProxy.bind(new Car());
        runAble.running();
        System.out.println("=============================================");
    
        RunAble runAble1 = (RunAble)runAbleProxy.bind(new Dog());
        runAble1.running();
    
        }}
    

    5. 결과

    $Proxy is ready to run. 
    Car is running 
    $Proxy had done. 
    =============================================
    $Proxy is ready to run. 
    Dog is running 
    $Proxy had done.
    

    그러나 JDK의 동적 에이전트는 인터페이스에 의해 이루어진다. 만약에 일부 종류가 인터페이스를 실현하지 못하면 JDK 에이전트를 사용할 수 없다. 그러면 cglib 동적 에이전트를 사용해야 한다.

    좋은 웹페이지 즐겨찾기