• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

java动态代理的2种实现方式

java 搞代码 4年前 (2022-01-09) 16次浏览 已收录 0个评论

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

先看一下Method中的invoke方法在api中是怎么描述的

 就是说调用处理程序对接口的实现类对象调用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()<div>本文来源gaodai.ma#com搞#代!码网_</div>;    }}

 控制台结果:

第二种方式有点小疑惑,不知道大家有没有,那就是并没有显示的调用NumProxyImpl中的invoke方法,可是却执行了,嗯嗯,这个自己下去看一下啊

不想麻烦的只需要记住就行了。

比如编码的处理就可以用到代理,下次写个例子。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java动态代理的2种实现方式

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址