概述

AOP用到了两种动态代理来实现织入功能:

  • jdk动态代理
  • cglib动态代理
  • 比较:
  • jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。
  • jdk动态代理的应用前提是目标类必须基于统一的接口。因此,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。

静态代理

  • 建一个接口,接口中定义相应(代理对象和目标对象都要实现)的 方法
public interface Subject{
void test();
}
  • 目标类(实现上述接口)
public class RealSubject implements Subject{@Overridepublic void tset(){System.out.printin("target method");}
}
  • 代理类(实现上述接口)
public class Proxy implements Subject{private RealSubject realSubject;public Proxy(RealSubject realSubject){this.realSubject = realSubject;}@Overridepublic void test(){System.out.printin("Before");try{realSubject.test();}catch(Exception e){System.out.println("ex:"+e.getmessage());throw e;}finally{System.out.println("After");}
}
}
  • 客户端调用
public class Client{
public static void main(String[] args){
//通过接口
Subject subject = new Proxy(new RealSubject());
subject.test();
}
}

动态代理

(静态代理缺点:不灵活,重复代码多)

基于接口代理(jdk)

  • 类:java.lang.reflect.Proxy(通过该类动态生成代理类)
  • 代理类实现接口:InvocationHandler
  • jdk代理只能基于接口动态代理(因为生成的proxy class中,继承了Proxy类,实现了需要代理的接口,而Java是单继承,多实现的处理方式)
  • 动态代理类
  • 实现接口的方法
  • 引用目标方法
  • 构造器注入目标方法
  • 通过反射调用目标方法
    public class JdkProxySubject implements InvocationHandler{//引入要代理的真实对象private RealSubject realSubject;//用构造器注入目标方法,给我们要代理的真实对象赋初值public JdkProxySubject(RealSubject realSubject){this.realSubJect=realSubject;}//实现接口的方法@Overridepublic Object invoke(Object proxy,Method method,Object[] args)throws Throwable{System.out.println("before");Object result = null;try{//调用目标方法//利用反射构造目标对象//    当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用result=method.invoke(realSubject,args);}catch(Exception e){System.out.println("ex:"+e.getMessage());throw e; }finally{System.out.println("after");}return result;}}
  • 客户端调用(使用Proxy)
  public class Client{public static void main(String[] args){//使用Proxy构造对象//参数//java泛型需要转换一下/* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数* 第一个参数 getClassLoader() ,我们这里使用Client这个类的ClassLoader对象来加载我们的代理对象* 第二个参数表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上* /Subject subject = (Subject) java.lang.reflect.Proxy.newProxyInstance(Client.class.getClassLoader(),new Class[]{Subject.class},new JdkProxySubject(new RralSubject()));//调用方法subject.test;}}
原理解析
过程
调用Proxy.newProxyInstance生成代理类的实现类:
  • 调用getProxyClass0寻找或生成指定代理类
    (从缓存中取,如果没有,就生成一个放在缓存中 : 通过ProxyClassFactory生成)
  • 缓存调用ProxyClassFactory生成代理类,proxy class的生成最终调用ProxyClassFactory的apply方法.
  • ProxyGenerator.generateProxyClass使用生成的代理类的名称,接口,访问标志生成proxyClassFile字节码
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);try {return defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);} catch (ClassFormatError e) {throw new IllegalArgumentException(e.toString());}
  • 生成字节码之后利用反射生成实例
    Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。
InvocationHandler接口:

每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable
我们看到这个方法一共接受三个参数,那么这三个参数分别代表什么呢?

-proxy:  指代我们所代理的那个真实对象
-method:  指代的是我们所要调用真实对象的某个方法的Method对象
-args:  指代的是调用真实对象某个方法时接受的参数

Proxy类
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:
这个方法的作用就是得到一个动态的代理对象,其接收三个参数,我们来看看这三个参数所代表的含义:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
  • loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载

  • interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法

  • h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

基于继承代理(cglib)

  • 代理类
 public class CglibMethodInterceptor implements MethodInterceptor{//主要的方法拦截类,它是Callback接口的子接口,需要用户实现@Overridepublic Object intercept(Object obj,Method method,Object[] args,MethodProxy proxy )throws Throwable{System.out.println("before cgplib");Object result = null;try{//利用反射创建代理对象 result = proxy.invokeSuper(obj,args);}catch(Exception e){System.out.println("ex:"+e.getMessage());throw e;}finally{System.out.println("after cglib");}return result;}}
  • 调用类
 public class Client{public static void main(String[] args){// 主要的增强类Enhancer enhancer=new Enhancer;//  目标类 , 设置父类,被增强的类enhancer.setSuperclass(RealSubject.class);// 回调对象enhancer.setCallback(new CglibMethodInterceptor());//生成代理类对象,用cglibProxy来增强RealSubjectSubject subject=enhancer.create();subject.test();}
}
原理解析

Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理:
CGLIB的核心类:

  • net.sf.cglib.proxy.Enhancer – 主要的增强类
  • net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
  • net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用:
  • Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。

-net.sf.cglib.proxy.MethodInterceptor接口是最通用的回调(callback)类型,它经常被基于代理的AOP用来实现拦截(intercept)方法的调用。这个接口只定义了一个方法

public Object intercept(Object object, java.lang.reflect.Method method,
Object[] args, MethodProxy proxy) throws Throwable;
  • 第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数。原来的方法可能通过使用java.lang.reflect.Method对象的一般反射调用,或者使用 net.sf.cglib.proxy.MethodProxy对象调用。net.sf.cglib.proxy.MethodProxy通常被首选使用,因为它更快。
Java字节码生成开源框架–ASM:

ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。


文章目录

  • 概述
  • 静态代理
  • 动态代理
    • 基于接口代理(jdk)
      • 原理解析
    • 基于继承代理(cglib)
      • 原理解析
      • Java字节码生成开源框架--ASM:

喜欢的话可以点点关注,或者添加作者微信,欢迎随时来撩

Java动态代理的实现原理相关推荐

  1. java动态代理实现与原理

    java动态代理实现与原理详细分析 关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式–代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式 代理模 ...

  2. java动态代理实现与原理详细分析(代码层面解释了AOP的实现)

    关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式    代理模式是常用的java设计模式, ...

  3. 高级JAVA - 动态代理的实现原理和源码分析

    在之前的一篇文章中 , 我们简单了解了一下代理模式(JAVA设计模式 - 代理模式) , 本篇我们来学习一下动态代理的实现原理 , 以及源码是怎样的 . JDK动态代理的主要实现步骤如下 : 1 . ...

  4. java动态代理实现与原理详细分析(【转载】By--- Gonjan )

    [转载]By---    Gonjan  关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式 ...

  5. (转)java动态代理实现与原理详细分析

    https://www.cnblogs.com/gonjan-blog/p/6685611.html 1.静态代理 静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类 ...

  6. 【java】java动态代理实现与原理详细分析

    文章目录 一.代理模式 二.静态代理 1.静态代理 2.静态代理简单实现 三.动态代理 1.动态代理 2.动态代理简单实现 四.动态代理原理分析 五.总结 关于Java中的动态代理,我们首先需要了解的 ...

  7. java动态代理实现与原理详细分析

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 一.代理 (1).什么是代理? 大道理上讲代理是一种软件设计模式,目 ...

  8. 02.Java动态代理实现与原理分析之静态代理

    一.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关 ...

  9. java高级----Java动态代理的原理

    Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程 ...

最新文章

  1. Pycharm上传Gitlab
  2. ms sql 聚合事例
  3. php+nginx上传文件配置
  4. 忍辱负重的小白兔们 - 验收准则的意义
  5. android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏
  6. 【转】使用PowerApps快速构建基于主题的轻业务应用 —— 进阶篇
  7. shell脚本修改文本中匹配行之前的行的方法
  8. 检错码之奇偶校验编码
  9. 百度排名规则及算法(百度内部资料)
  10. 徐思201771010132《面向对象程序设计(java)》第十四周学习总结
  11. 上海计算机科学大学排名,2019上海软科世界一流学科排名计算机科学与工程专业排名卡耐基梅隆大学排名第4...
  12. 计算机专业正高职称怎么获得,正高级软件工程师职称认定办理
  13. Skype、MSN/Live Messenger、Lync全面整合
  14. SoX使用手册(中文版)
  15. python西瓜视频UP主所有视频封面下载
  16. 百度,谷歌,360,神马,必应,搜狗搜索引擎网站链接提交入口
  17. 西安交通大学大计基第十四周练习题
  18. 2022年,关于副业赚钱和自主创业的一些建议
  19. 北工大计算机网络95分复习——【第四章 介质访问控制子层】
  20. S7-200SMART指针学习(二)指针的内部结构

热门文章

  1. 阴阳师乐视版。。。。。。
  2. jenkins连接mysql_mysql – 如何将JDBC驱动程序添加到Jenkins管道?
  3. 嘉立创元器件导入AD20
  4. 企业微信支付的接口开发总结
  5. UESTC--1251--谕神的密码(贪心)
  6. 【庖丁解牛】Navicat for MySQL连接时候报错1251无法连接MySQL
  7. 全球及中国脂肪酸盐行业商业模式分析及投资风险预测2022年版
  8. 基于OpenCV的全景拼接
  9. 计算机基础教程试题及答案,计算机基础教程考试题「附答案」
  10. 电销系统提升企业形象,促进市场效益大化