一、代理是什么

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

通俗的讲,在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。例如,购买火车票不一定要去火车站买,可以通过 携程或者淘宝上买。又比如,找保姆、找工作等都可以通过找58或boss等网站中介完成。

二、代理的实现

在java中代理实现的方式有两种,一种是通过继承的方式,另一种是通过组合的方式去实现。

1.继承模式

package com.example.demo.proxy;public class HouseOwner {public void rent() {System.out.println("和房东签署协议,租房完成!");}
}
package com.example.demo.proxy;public class Intermediary extends HouseOwner {public void rent() {System.out.println("找房....");super.rent();System.out.println("收房租....");}
}
package com.example.demo.proxy;public class Test {public static void main(String[] args) {HouseOwner houseOwner = new Intermediary();houseOwner.rent();}
}

2.组合模式

组合模式有三个关键点:

  • 代理类和被代理类实现同一接口
  • 代理类持有被代理类的接口引用。
  • 代理类通过构造函数函数传入被代理类。
package com.example.demo.proxy;public interface Owner {void rent();
}
package com.example.demo.proxy;public class HouseOwner implements Owner {public void rent() {System.out.println("和房东签署协议,租房完成!");}
}
package com.example.demo.proxy;public class Intermediary implements Owner {private Owner owner;public Intermediary(Owner owner) {this.owner = owner;}public void rent() {System.out.println("找房....");owner.rent();System.out.println("收房租....");}
}
package com.example.demo.proxy;public class Test {public static void main(String[] args) {Owner owner = new Intermediary(new HouseOwner());owner.rent();}
}

三、jdk动态代理实现

package com.example.demo.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class Intermediary implements InvocationHandler {private Owner target;public Intermediary(Owner target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("找房....");//通过反射执行目标方法Object result = method.invoke(target, args);System.out.println("收房租....");return result;}
}
package com.example.demo.proxy;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {HouseOwner houseOwner = new HouseOwner();Owner owner = (Owner) Proxy.newProxyInstance(houseOwner.getClass().getClassLoader(), houseOwner.getClass().getInterfaces(), new Intermediary(houseOwner));owner.rent();}
}

四、jdk动态代理实现原理

jdk动态代理的实现与上面讲的组合模式实现代理基本一样,只不过不是在编译前手动编写的代理类,而是在运行时通过反射的方式,动态的生成了代理类,所以称为动态代理。

核心实现源码:


package java.lang.reflect;import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiFunction;
import sun.misc.ProxyGenerator;
import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;public class Proxy implements java.io.Serializable {private static final long serialVersionUID = -2222568056686623797L;private Proxy() {}protected Proxy(InvocationHandler h) {Objects.requireNonNull(h);this.h = h;}@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{Objects.requireNonNull(h);final Class<?>[] intfs = interfaces.clone();Class<?> cl = getProxyClass0(loader, intfs);try {if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), cl);}final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {cons.setAccessible(true);return null;}});}return cons.newInstance(new Object[]{h});} catch (IllegalAccessException|InstantiationException e) {throw new InternalError(e.toString(), e);} catch (InvocationTargetException e) {Throwable t = e.getCause();if (t instanceof RuntimeException) {throw (RuntimeException) t;} else {throw new InternalError(t.toString(), t);}} catch (NoSuchMethodException e) {throw new InternalError(e.toString(), e);}}
}

通过 newProxyInstance方法,jdk在运行时动态生成了代理类$proxy0,并加载到了虚拟机中,这个类实际是不存在的。

$proxy0类的代码如下:


package com.example.demo.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;public final class $Proxy0 extends Proxy implements Owner {private static Method method;static {try {method = Class.forName("com.example.demo.proxy.Owner").getMethod("rent");} catch (NoSuchMethodException | ClassNotFoundException e) {e.printStackTrace();}}public $Proxy0(InvocationHandler invocationHandler) {super(invocationHandler);}public final void rent() {try {super.h.invoke(this, method, new Object[]{});} catch (Throwable throwable) {throwable.printStackTrace();}}
}

jdk动态代理的原理相关推荐

  1. Spring 初识Aop JDK动态代理实现 原理初显

    Spring 初识Aop JDK动态代理实现 原理初显 一.项目结构 二.具体步骤: 1.创建maven项目 创建好包结构 2.写一个TestDao接口 及实现类 3. 写一个自己的切面类 4.jav ...

  2. JDK动态代理实现原理--转载

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的,直到前几个星期才把这些问题全部搞明白了.  ...

  3. JDK动态代理实现原理详解(源码分析)

    无论是静态代理,还是Cglib动态代理,都比较容易理解,本文就通过进入源码的方式来看看JDK动态代理的实现原理进行分析 要了解动态代理的可以参考另一篇文章,有详细介绍,这里仅仅对JDK动态代理做源码分 ...

  4. jdk动态代理实现原理

    写在前面: 大神和diao炸天的亲请绕道.. 关于代理模式的概念这里省去,大家可以放鸟尽情搜.. 关于为什么叫动态代理,个人理解是代理的类是在运行时动态生成的,大家也可以参考网上的理解.. 文笔很差, ...

  5. 【干货】JDK动态代理的实现原理以及如何手写一个JDK动态代理

    动态代理 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 在解 ...

  6. 08.jdk动态代理原理

    课程标题<jdk动态代理底层原理分析> 课程内容: 1.什么是代理模式 2.代理模式应用场景有哪些 3.代理模式实现方式有哪些 4.静态代理与动态代理区别 5.JDK动态代理原理分析 6. ...

  7. 两万字吐血总结,代理模式及手写实现动态代理(aop原理,基于jdk动态代理)

    代理模式及手写实现动态代理 一.代理模式 1. 定义 2. 示例 (1)静态代理 (2)动态代理 3. 通用类图 4. 代理模式的优点 二.jdk动态代理实现原理 1. jdk动态代理源码分析(通过该 ...

  8. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  9. 一文理解JDK静态代理、JDK动态代理、Cglib动态代理

    代理模式 通过代理来访问真实的对象,而不是直接去访问真正干活的对象,比如二房东租房,二房是代理者,而一房东才是真正的房东:或者说生活中的中介.Spring中的AOP就是动态代理 适用场景 需要动态修改 ...

  10. jdk动态代理proxy

    目录 jdk和cglib区别 以下案例: 定义共同行为接口 被代理类(目标类) jdk动态代理类-动态生成代理类和被代理方法的调用 解析动态生成的代理类$Proxy0.class 静态代理需要自己实现 ...

最新文章

  1. 2017年热度最高的十大技术类技能
  2. 科大星云诗社动态20210826
  3. SpringBoot集成多数据源
  4. 局域网即时通讯的可管理性
  5. 实用常识 | 一篇文章记录如何轻松清理C盘,C盘又满了,继续盘它
  6. Python面向对象,站在更高的角度来思考
  7. NumberUtils的 isParsable(String)和isCreatable(String)方法
  8. android错误怎么关机,Android系统小技巧:系统崩溃了只重启部分子系统,而不是全部重启...
  9. Android 开发之 bindService() 通信
  10. 自定义数组名做参数(传指针教学)
  11. kindeditor不过滤标签属性
  12. Xv6 Page Table
  13. (matlab代码)绘制地震记录的F-K谱
  14. python turtle库下载_python3中安装turtle库
  15. CareUEyes Pro(电脑防蓝光软件)官方中文版V2.1.0.0 | 超实用电脑护眼软件下载-学生白领必备护眼神器!!
  16. WPF实现截图功能——WPF制作文字OCR软件(三)
  17. java导出excel设置行高列宽_Java 设置Excel自适应行高或列宽
  18. HDU 5755 Gambler Bo(数论)
  19. [转]优秀的计算机编程类博客 和 文章
  20. 如何计算满足指定条件下数值的平均值——DAVERAGE函数的使用

热门文章

  1. DOSBox下载安装
  2. Arduino库文件LiquidCrystal的实用方法
  3. idcsystem源码php_最新PHP宝塔IDC分销系统源码
  4. sql server插入语句
  5. 360浏览器的html在哪里,360浏览器收藏夹路径在哪里
  6. QT应用编程: windows下QT调用COM组件
  7. c++ strcmp函数
  8. JEB动态调试与篡改攻防世界Ph0en1x-100
  9. 水泥电阻,常用电阻 阻值表
  10. 计算机打字键盘亮怎么设置,win7系统键盘灯亮着但是不能打字的解决方法?