>  기사  >  类库下载  >  Java 동적 프록시를 구현하는 2가지 방법

Java 동적 프록시를 구현하는 2가지 방법

高洛峰
高洛峰원래의
2016-11-30 14:59:302327검색

Java의 동적 프록시에 대해서는 Java에 연결하는 API에 설명되어 있으므로 여기서는 쓰지 않겠습니다. 내가 이해하는 프록시:

특정 인터페이스에서 특정 메서드의 기능을 확장하는 것이 프록시입니다. 프록시는 프록시 인스턴스와 연결된 호출 처리기 개체를 통해 메서드를 호출합니다.

예를 살펴보겠습니다:

인터페이스:

public interface Num {
    void show();
    
    int getNum();
    
    int getProduct(int x);
}

구현 클래스:

public class MyNum implements Num {
    @Override
    public int getNum() {
        return 3;
    }
    
    @Override
    public int getProduct(int x) {
        return x;
    }

    @Override
    public void show() {
        System.out.println("底层方法打印数字99");
    }
}

먼저 호출 메서드를 살펴보겠습니다. in Method API에서 어떻게 설명되나요?

Java 동적 프록시를 구현하는 2가지 방법

은 호출 핸들러가 인터페이스의 구현 클래스 개체에서 Method 개체로 표시되는 기본 메서드를 호출한다는 의미입니다.

프록시를 구현하는 첫 번째 방법:

public class NumProxy {
    private Object num;

  //通过构造方法构造接口的实现类对象
    public NumProxy(Object num) {
        this.num = num;
    }

    public Object getNumByProxy(){
        Object numProxy =  Proxy.newProxyInstance(num.getClass().getClassLoader(), new Class[]{Num.class}, new InvocationHandler() {
            /**
             * method: 对应于在代理实例上调用的接口方法的 Method 实例。我理解的就是被代理的真实方法实例
             * args: 我理解的是真实方法的参数数组
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                Object obj = null;
                System.out.println("在方法之前开始记录");
                String methodName = method.getName();
                if("getProduct".equals(methodName)){
                    obj = method.invoke(num, args);
                    obj = (Integer) obj * 2;
                    System.out.println("proxy: getProduct()结束");
                }
                else if("show".equals(methodName)){
                    obj = method.invoke(num, args);
                    System.out.println("proxy: show()结束");
                }
                return obj;
            }
        });
        return numProxy;
    }
}

프록시를 구현하는 두 번째 방법: InvocationHandler 인터페이스 구현

public class NumProxyImpl implements InvocationHandler {
  //这里我把接口类型具体化了, 没有写成Object
    private Num num;
    
    public NumProxyImpl(Num num){
        this.num = num;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object obj = null;
        String methodName = method.getName();
        if("getProduct".equals(methodName)){
            System.out.println("proxy: getProduct()开始");
            obj = method.invoke(num, args);
            obj = (Integer) obj * 2;
            System.out.println("proxy: getProduct()结束");
        }else if("show".equals(methodName)){
            System.out.println("proxy: show()开始");
            obj = method.invoke(num, args);
            System.out.println("proxy: show()结束");
        }
        return obj;
    }
}

테스트 코드:

public class TestNum {
    public static void main(String[] args) {
    //两种方式一起测试
        NumProxy np = new NumProxy(new MyNum());
        Num numProxy = (Num) np.getNumByProxy();
        int x = numProxy.getProduct(2);
        System.out.println(x);
        numProxy.show();
        
        System.out.println("----------------");
        NumProxyImpl npi = new NumProxyImpl(new MyNum());
        Num numPro = (Num) Proxy.newProxyInstance(Num.class.getClassLoader(), new Class[]{Num.class}, npi);
        int n = numPro.getProduct(3);
        System.out.println(n);
        numPro.show();
    }
}

콘솔 결과:

Java 동적 프록시를 구현하는 2가지 방법

두 번째 방법은 약간 혼란스럽습니다. 해당 방법이 있는지는 모르겠습니다. 즉, NumProxyImpl의 호출입니다. 메소드가 명시적으로 호출되지는 않았지만 구현되었습니다. 어, 음, 직접 가서 살펴보세요

귀찮게 하고 싶지 않다면 기억해 두세요.

예를 들어 인코딩 처리에는 프록시를 사용할 수 있습니다. 다음에 예시를 작성하겠습니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:Java 수정자 분석다음 기사:Java 수정자 분석