java动态代理笔记

以下代码是我在下面这篇博客看到的,因为有些地方不理解,所以先按自己的方式背下来。

代理模式其实就是为了增强现有的功能。下面是卖酒的动态代理的例子。

卖酒需要实现下面这个接口(类似于卖酒许可证)

package com.frank.test;  
public  interface  SellWine  {  
void  mainJiu(); 
}

卖茅台酒需要实现卖酒接口。可是下面卖茅台酒的功能过于简单,我们想使用代理模式对其增强。

public class MaotaiJiu implements SellWine {

    @Override
    public void mainJiu() {
        // TODO Auto-generated method stub
        System.out.println("我卖得是茅台酒。");
    }
}

通过java内置的 Proxy静态方法 newProxyInstance 可以动态创

建代理。

public static Object newProxyInstance(ClassLoader loader,
  Class<?>[] interfaces, InvocationHandler h)

newProxyInstance方法包含三个参数

ClassLoader:类加载器

它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器(固定写法: 被代类.getClass().getClassLoader())。

Class[]:代码要用来代理的接口(固定写法: 被代理类.getClass().getInterfaces())。

InvocationHandler:用于提供增强的代码,它是一个接口。通过实现它内部的invoke方法对代理对象进行增强。

invoke方法有三个参数:

invoke(Object proxy, Method method, Object[] args

  • proxy 代理对象的引用
  • method 代理对象调用的方法
  • args 调用的方法中的参数

我们不需要传上面三个参数,只要实现invoke方法的方法体就行了。

public class GuitaiA implements InvocationHandler {
    
    private Object pingpai;
        
    public GuitaiA(Object pingpai) {
        this.pingpai = pingpai;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("销售开始  柜台是: "+this.getClass().getSimpleName());
        method.invoke(pingpai, args);
        System.out.println("销售结束");
        return null;
    }
}

上面代码主要就 method.invoke(pingpai, args)
这句难以理解。 它的含义是对被代理对象pingpai的method方法传入参数args,它是原有方法在代理类中的体现形式。

测试

使用动态代理来代理 茅台酒

InvocationHandler jingxiao1 = new GuitaiA(maotaijiu)构造方法会把maotaijiu传给柜台对象的Pingpai变量。dynamicProxy.mainJiu()调用卖酒方法,因为是代理茅台的卖酒,所以InvocationHandler中method方法就是mainjiu。method.invoke(pingpai, args)会执行pingpai为maotai的mainjiu方法。

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        MaotaiJiu maotaijiu = new MaotaiJiu();
               
        InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);
        
        SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
                MaotaiJiu.class.getInterfaces(), jingxiao1);
    
        dynamicProxy.mainJiu();            
    }
}

原文 

https://segmentfault.com/a/1190000022166548

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » java动态代理笔记

赞 (0)
分享到:更多 ()

评论 0

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