专栏首页EffectiveCodingJVM 《八 JVM JDK代理&CGLib 代理解析》

JVM 《八 JVM JDK代理&CGLib 代理解析》

前言&背景 现在Spring 什么的好火。 Spring 很经典的一个特性是AOP AOP 的基础是代理。 代理分为静态代理、动态代理。 静态代理,不好处挺明显的,工程中各式各样的代理代码,过于冗余。 动态代理显得就简洁多了。 动态代理在java中现在大约有这么两种技术。JDK 原生反射,字节码操作增强反射(我第一次学到这个的时候感觉特别特别高大上,虽然现在也这么感觉 然后字节码操作技术 比较火的就是ASM了,也就是CGLib所使用的技术。 至于啥是代理,就不多解释了。就是产生一个代理操作来替代原核心操作并且增加一些便利的具有各个场景特性的附加操作。 然后JDK&CGLib表象上或者语法上的区别,一个面向接口、一个面向类、Spring 根据情况使用也可强制。然后单独使用的时候写法儿上的不同。 那在JVM层面去看待这个问题是怎样的呢? 其实本质要讨论的就是Java 反射、字节码操作具体是怎么样的,有什么区别。 先说一个反射的总体概念 反射,顾名思义 反着射,跟常规编写、编译、解释执行不同。我当时看反射的时候挺蒙蔽的,反射?反?射?到系统的看编程思想的RTTI那一块,对于反射的定义还有这个名字多少有点认可了。 下面是百度的解释,感觉挺糟糕的 也就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 一个比较可取的解释 Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions The primitive Java types (boolean, byte, char, short, int, long, float, anddouble), and the keyword void are also represented as Class objects. 综合起来看,也就是运行期间根据名称去动态的加载及使用一个编译期未知的类,然后根据加载进来的Class对象,来调用该类具体的方法的行为。(静态加载、根据已知信息直接使用) 为什么是反着呢,因为我们常规写程序都是既定使用的类&方法然后import、然后加载产生Class对象&使用类的具体信息 驱动执行。(已知信息使用) 而反射是在运行时除了名称完全未知,通过名称获取&加载进来,然后产生Class对象,通过Class 对象的信息来获取调用这个类具体的内容。(动态加载、透过 Class 获取信息去调用) 当然,这个类通常是远程调用或者别的什么方式来获取使用的。 Java反射也就是上面说的常规过程,来加载&使用一个完全未知的类。 而且JDK代理有个特点,是针对接口来实现的,也就是面向接口来编程,这也就导致了 接口一致而非对象一致。并且Java 反射效率总体来说是比较低下。 为了解决这些个问题,ASM之类的字节码操作技术出现了。

拿ASM 来说

这些类似的字节码操作技术其实也就是对 Class 文件的CURD来改变类的信息还有一些行为,甚至会产生一新类。来完成我们运行时的的一些动态加载需求。 其中ASM核心类有 ClassLoader(解析Class 文件用)、ClassWriter(重新构建编译的类)、ClassAdapter(委托方法调用给同样实现ClassVister接口的对象) 有兴趣可以去看看ASM,各式各样的设计模式。什么 访问者、职责链、桥接 都有。读码学习~ 然后ASM使用还是很广泛的,CGLib、Hibernate的懒加载都用到了,熟悉Hibernate的同学应该很清楚(在内存中生成的对象并不是你实现的那个类)。ASM效果很明显,事件驱动、可以只关心对其编程有意义的地方,效率还高。 然后这一篇放在这里说感觉比较合适,因为前刚推完加载过程、Class文件、对象什么,对于理解反射更合适吧

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • jvm源码解析(八)动态代理是如何实现的,JDK Proxy于CGLib有什么区别

    程序在运行期间可以访问、检测和修改其本身状态或行为的一种能力,使用反射我们可以调用任意一个类对象,以及类对象中包含的属性及方法

    用户6203048
  • 围绕Java反射,BAT的面试官可以问出多少花样

    关于反射,我必须要吐槽一下,初学的时候如果靠看xxx从入门到精通系列的书,理解反射可太TM困难了,看的我怀疑人生,那个时候我一度怀疑,我该不是个智障吧!

    王炸
  • 详解Java动态代理机制(二)----cglib实现动态代理

         上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我...

    Single
  • 金三银四面试季节——Java 核心面试技术点-《JVM篇》

    从性能的角度看,通常关注三个方面,内存占用(footprint)、延时(latency)和吞吐量(throughput),大多数情况下调优会侧重于其中一个或者两...

    烂猪皮
  • jdk静态代理,jdk动态代理,cglib动态代理

    代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道。如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法...

    互扯程序
  • 动态代理(2)

    JDK 动态代理有一个最致命的问题是其只能代理实现了接口的类。为了解决这个问题,我们可以用 CGLIB 动态代理机制来避免。

    黑洞代码
  • 深入浅出MyBatis:反射和动态代理

    前三篇详细总结了Mybatis的基本特性、常用配置、映射器,相对于Hibernate,映射器的配置相对复杂,但有很好的灵活性和扩展性,可以应对各种业务场景。熟练...

    情情说
  • Java面试快问快答-Instrument机制

    使开发者可以构建一个独立于应用程序的代理程序Agent,用来监控和协助运行在JVM上的程序,更重要的是能够替换和修改某些类的定义;

    JavaEdge
  • JDK动态代理与CGLib动态代理

    JDK1.3以后java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,动态代理是实现AOP的绝好底层技术。

    Jack Chen

扫码关注云+社区

领取腾讯云代金券