2021SC@SDUSC

动态代理

jdk的动态代理只能代理那些实现某个接口的类
如果一个类没有实现接口则需要用cglib去代理

JDK动态代理的原理
用代码去生成代买的过程
JDK动态代理的核心就是反射和动态生成Class对象。
有两个核心类组件,类:Proxy和接口:InvocationHandler。
我们自己的handler要实现InvocationHandler接口,
创建被代理对象时调用Proxy.newProxyInstance()方法 传入的参数有三个
1:被代理对象的类加载器
2:被代理对象的interfaces
3:MyInvocationHandler
用于动态创建 代理类。
代理类 extends 了 Proxy 并也 implements 了 被代理对象 实现的接口

1:我们传入的MyInvocationHandler对象就放在了Proxy类里
Proxy的一个构造方法protected Proxy(InvocationHandler h) {Objects.requireNonNull(h);this.h = h;}
$Proxy0的构造方法public $Proxy0(InvocationHandler param1) {super(var1);}
2:执行代理对象的方法实际上就是调用的我们传入的MyInvocationHandler的invoke方法,所以toString,hashCode,equal等方法也都被加强了!!!!但是那些wati,notify方法没有被加强public final String action() {//看这里!!!!//强转的类型就是,方法的返回值类型return (String)super.h.invoke(this, m3, (Object[])null);}

通过反射可以获得关于一个类的有关信息,比如有哪些成员方法,有哪些构造方法,并包装成Method,Constructor等对象
最终形成代理类的结构跟静态代理中代理类差不多

3:生成的动态代理类,里面有一个静态代码块,用来通过反射获取被代理对象需要被加强方法的method对象static {try {m0 = Class.forName("java.lang.Object").getMethod("hashCode");m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m2 = Class.forName("java.lang.Object").getMethod("toString");//通过反射获得一个类中的方法m3 = Class.forName("proxy.Subject").getMethod("action");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}
public interface Subject {String action();
}public class RealSubject implements Subject{public Integer integer = 0;@Overridepublic String action() {System.out.println("action in RealSubject");return "action done";}
}public class ProxyInvocationHandler implements InvocationHandler {protected Subject subject;public ProxyInvocationHandler(Subject subject) {this.subject = subject;}public void before() {System.out.println("before");}public void after() {System.out.println("after");}//proxy是代理对象,就是说是com.sun.proxy.$Proxy0的实例//两个作用//1:使用反射获取代理对象的信息(比如proxy.getClass().getName())。//2:返回代理对象以进行连续调用(前提是代理对象被执行的方法返回值类型实现了Subject接口// https://blog.csdn.net/ruidianbaihuo/article/details/96622992@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    before();Object ob = method.invoke(subject,args);//这里ob的类型为method的返回值类型after();return ob;}
}Subject realSubject = new RealSubject();//被代理的类//动态生成的代理对象Subject proxyRealSubject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),//被代理对象的类加载器realSubject.getClass().getInterfaces(), //被代理对象实现的接口的接口方法列表proxyInvocationHandler);System.out.println(realSubject.getClass());System.out.println(proxyRealSubject.getClass());System.out.println(realSubject.getClass() == proxyRealSubject.getClass());输出class proxy.RealSubjectclass com.sun.proxy.$Proxy0 //这个目录只在运行期间存在false

我们可以发现这根本就是两个不同的字节码文件,一个是我们自己创建的类对象,一个是jdk动态生成的类对象
如何保存JDK动态代理生成的class文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.sun.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import proxy.Subject;public final class $Proxy0 extends Proxy implements Subject {//也继承了Subject接口private static Method m0;private static Method m1;private static Method m2;private static Method m3;public $Proxy0(InvocationHandler param1) {super(var1);}public final int hashCode() {try {return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean equals(Object var1) {try {return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String toString() {try {return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String action() {//看这里!!!!try {//强转的类型就是,方法的返回值类型return (String)super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m0 = Class.forName("java.lang.Object").getMethod("hashCode");m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m2 = Class.forName("java.lang.Object").getMethod("toString");//通过反射获得一个类中的方法m3 = Class.forName("proxy.Subject").getMethod("action");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}
}

山东大学移动信息门户04相关推荐

  1. 山东大学移动信息门户03

    2021SC@SDUSC 线程的状态 yield()方法仅释放CPU执行权,锁仍然占用 wait(方法会释放锁) 中断 wait()是能中断 否则会抛出java.lang.InterruptedExc ...

  2. 山东大学移动信息门户11

    2021SC@SDUSC 控制器:负责处理传入的 请求 和向客户端返回 响应 路由:每一个URL都是由网站的服务器端程序来接收并进行处理,最终定向到相应的资源的机制. 通常,每个控制器有多个路由,不同 ...

  3. SDU信息门户(12)系统配置的yaml文件解析

    2021SC@SDUSC 目录 一.引言 二.docker安装及yaml文件分析 1.安装 2.yaml文件分析 version build cap_add,cap_drop cgroup_paren ...

  4. 复习Java第一个项目学生信息管理系统 04(权限管理和动态挂菜单功能) python简单爬数据实例Java面试题三次握手和四次挥手生活【记录一个咸鱼大学生三个月的奋进生活】016

    记录一个咸鱼大学生三个月的奋进生活016 复习Java(学生信息管理系统04权限管理和动态挂菜单功能) 改写MainFrame的构造方法 新增LoginFrame的验证登录是否成功的代码 新增Logi ...

  5. (附源码)ssm经济信息门户网站 毕业设计 141634

    ssm经济信息门户网站 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用.信息时代的到来已成为不可阻挡的时尚潮流,人类发展 ...

  6. ssm经济信息门户网站 毕业设计源码141634

    ssm经济信息门户网站 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用.信息时代的到来已成为不可阻挡的时尚潮流,人类发展 ...

  7. 天津理工大学邮箱服务器,天津理工大学信息门户

    [www.chinawenwang.com--百科] 天津理工大学是一所以工为主,工理结合,工.理.管.文.艺等多学科发展的天津市市属普通高等学校.中国文库网为大家带来的天津理工大学信息门户,希望能帮 ...

  8. ArcGIS在线应用介绍(12)华盛顿州地质信息门户

    华盛顿州地质信息门户(Washington State Geologic Information Portal) 开发语言:flex SDK:ArcGIS API for flex ArcGIS产品: ...

  9. 将进酒计算机应用技术学院信息门户,智慧校园信息门户

    黄河水利职业技术学院信息门户是一个面向全体师生的个性化应用集成和数据信息整合平台,它为师生访问信息化校园的应用服务和有关信息提供了方便快捷的统一人口,系统拥有风格管理.页面设置.日程安排等友好而又灵活 ...

最新文章

  1. 图灵十二月书讯 ——年底大餐
  2. PageOffice,word常用接口对象--Paragraph类
  3. 个人开发者帐号+wireless install 实现非app store程序的在线更新功能
  4. python快速入门答案-Python 快速入门笔记(1):简介
  5. Android学习笔记之android:collapseColumns,android:shrinkColumns和stretchColumn
  6. 【前端就业课 第一阶段】HTML5 零基础到实战(十一)canvas 基础
  7. c vector用法是什么
  8. 三大工艺因素影响百万像素镜头成像质量
  9. python对于一元线性回归模型_Python|机器学习-一元线性回归
  10. asp.net使用Mysql乱码处理
  11. 电视直播源码2.0-全站HTML文件
  12. 高中数学 经典题选 排列 组合 概率
  13. 数学史思维导图_趣谈数学历史:数学发展简史思维导图——中国、外国数学发展...
  14. 聚宽macd底背离_看图学大级别MACD底背离
  15. Qt实现类似QQ头像
  16. VS2013中关于gets函数使用问题的解决方案(搬运“尼古拉斯罗本”的部分文章,)
  17. [读书笔记]-《高能要事》-一次做好一件事
  18. 真相:为什么投简历总是没回音?
  19. 日本美术学校有哪些,日本美术学校排名榜
  20. 微信小程序图书馆座位预约系统设计与实现 毕业设计论文 课题题目参考(2)后台管理功能、界面参考

热门文章

  1. Mount 命令参数详解
  2. 视频工厂解读视频拍摄方法
  3. Photoshop CS6去除数码照片画面中的噪点实例详解教程
  4. macos挂载磁盘映像_如何在Windows 7、8和10中挂载ISO映像
  5. 破解万象040608
  6. wma转mp3怎么弄_wma转mp3格式转换器
  7. CentOS8安装artifactory社区版
  8. ns-3构建简单点对点网络
  9. 网络安全季度总结:盘点2021年第一季度国内网络安全大事件
  10. 如何对准UBNT airFiber网桥天线