代理类

1.接口代理,必须有接口和子实现:

实现一个代理,需要公共接口,实现接口的目标类,代理类,通过代理类构造函数传入目标类入参来持有目标类的具体实例,代为执行具体类实例方法。分为动态代理(接口实现)和静态代理,静态代理在编译时已经确定实际类

动态代理(JDK):在运行时动态生成,通过proxy类和invocationhandler接口动态生成代理类和代理对象。内部通过反射机制生成代理方法。

生成步骤:定义公共接口,实现公共接口的目标类(被代理对象)。实现invocationhandler接口的类传入被代理对象。proxy.newProxyInstance实例生成代理类实例。

原理:Proxy.getProxyClass获取到代理类,通过代理类.getConstructor生成构造器。Constructor.newInstance生成代理类实例。内部Proxy.getProxyClass其实是通过反射机制生成了一个代理类Proxy0 extend Proxy Imple 公共接口,Proxy 类持有InvocationHandler对象(入参传入的是目标类). 生成的动态代理类里边有代理接口的方法(内部调用handler.invoke(this,m3,null)),其实代理类实例调用的方法就是内部handler调用invoke,而handler.invoke我们有自己的实现。

java内存反编译出来的类:

proxy.Person;publicfinalclass$Proxy0extendsProxyimplements Person

{

  privatestatic Method m1;

  privatestatic Method m2;

  privatestatic Method m3;

  privatestatic Method m0;


  /**  *注意这里是生成代理类的构造方法,方法参数为InvocationHandler类型,看到这,是不是就有点明白

  *为何代理对象调用方法都是执行InvocationHandler中的invoke方法,而InvocationHandler又持有一个

  *被代理对象的实例,不禁会想难道是....? 没错,就是你想的那样。

  *

  *super(paramInvocationHandler),是调用父类Proxy的构造方法。

  *父类持有:protected InvocationHandler h;

  *Proxy构造方法:

  *    protected Proxy(InvocationHandler h) {

  *        Objects.requireNonNull(h);

  *        this.h = h;

  *    }

  *

  */public $Proxy0(InvocationHandler paramInvocationHandler)

    throws

  {

    super(paramInvocationHandler);

  }


  //这个静态块本来是在最后的,我把它拿到前面来,方便描述static  {

    try    {

      //看看这儿静态块儿里面有什么,是不是找到了giveMoney方法。请记住giveMoney通过反射得到的名字m3,其他的先不管m1 = Class.forName("java.lang.Object").getMethod("equals",newClass[] { Class.forName("java.lang.Object") });

      m2 = Class.forName("java.lang.Object").getMethod("toString",newClass[0]);

      m3 = Class.forName("proxy.Person").getMethod("giveMoney",newClass[0]);

      m0 = Class.forName("java.lang.Object").getMethod("hashCode",newClass[0]);

      return;

    }

    catch (NoSuchMethodException localNoSuchMethodException)

    {

      thrownew NoSuchMethodError(localNoSuchMethodException.getMessage());

    }

    catch (ClassNotFoundException localClassNotFoundException)

    {

      thrownew NoClassDefFoundError(localClassNotFoundException.getMessage());

    }

  }

  /**  *

  *这里调用代理对象的giveMoney方法,直接就调用了InvocationHandler中的invoke方法,并把m3传了进去。

  *this.h.invoke(this, m3, null);这里简单,明了。

  *来,再想想,代理对象持有一个InvocationHandler对象,InvocationHandler对象持有一个被代理的对象,

  *再联系到InvacationHandler中的invoke方法。嗯,就是这样。

  */publicfinalvoid giveMoney()

    throws

  {

    try    {

      this.h.invoke(this, m3,null);

      return;

    }

    catch(Error|RuntimeException localError)

    {

      throw localError;

    }

    catch (Throwable localThrowable)

    {

      thrownew UndeclaredThrowableException(localThrowable);

    }

  }

  //注意,这里为了节省篇幅,省去了toString,hashCode、equals方法的内容。原理和giveMoney方法一毛一样。}

因为有继承,所以这种实现只能对接口进行代理,不能对类进行代理

参考资料:https://www.cnblogs.com/gonjan-blog/p/6685611.html

2:子类继承方式代理:Cglib代理

使用Enchancer类指定代理父类和回调拦截方法实现动态代理,在内存中创建一个代理类的子类。基于字节码实现,通过在子类中通过拦截的方式拦截父类方法调用

反射:根据路径获取class,创建class实例,根据class获取方法:method是父子类全部public,dechared是当前类的所有方法。method.invoke(实例,参数)。一般效率没有那么低,虽然有验证,递归循环等操作,但是method也放入了一些缓存

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341