Home  >  Article  >  类库下载  >  2 ways to implement java dynamic proxy

2 ways to implement java dynamic proxy

高洛峰
高洛峰Original
2016-11-30 14:59:302377browse

Java's dynamic proxy is explained in the Java API, so I won't write it here. The proxy I understand:

 Extending the functionality of a specific method in a specific interface is a proxy. A proxy invokes methods through the invocation handler object associated with the proxy instance.

Let’s take a look at an example:

Interface:

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

Implementation class:

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");
    }
}

Let’s first look at how the invoke method in Method is described in the api

2 ways to implement java dynamic proxy

That is to say, the handler is called on the interface The implementation class object calls the underlying method represented by the Method object.

The first way to implement the proxy:

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;
    }
}

The second way to implement the proxy: By implementing the InvocationHandler interface

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;
    }
}

Test code:

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();
    }
}

Console result:

2 ways to implement java dynamic proxy

The second way is a little confusing , I don’t know if you have it, but the invoke method in NumProxyImpl is not explicitly called, but it is executed. Hmm, go check it out for yourself

If you don’t want to bother, just remember it.

For example, proxy can be used for encoding processing. I will write an example next time.


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn