jvm源码解析(八)动态代理是如何实现的,JDK Proxy于CGLib有什么区别
动态代理常用实现方式是反射,是一种行为方式,而反射或ASM只是它的一种实现手段
反射机制:
程序在运行期间可以访问、检测和修改其本身状态或行为的一种能力,使用反射我们可以调用任意一个类对象,以及类对象中包含的属性及方法
JDK Proxy和CGLib的区别
- JDK Proxy是java语言自带的功能,无需通过加载第三方类实现
- Java对JDK Proxy提供了稳定的支持,并且会持续的升级和更新JDK Proxy,例如Java8中JDK Proxy性能相比于之前版本提升了很多
- JDK Proxy是通过拦截器+反射的方式实现的
- JDK Proxy只能代理实现接口的类
- JDK Proxy实现和调用起来都比较简单
- CGLib是第三方提供的工具,基于ASM实现的,性能较高
- CGLib无需通过接口来实现,它是通过实现子类的方式来完成调用的
常见问题:
考核你对JDK Proxy和CGLib的掌握程度
JDK Proxy的核心是实现InvocationHandler接口,来获得动态代理的能力
接口中只有一个invoke方法,InvocationHandler是动态代理的代理器,invoke方法是触发执行代理的方法。
CGLib使用前,先在pom.xml中加入依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
实现接口MethodInterceptor,接口中有一个intercept方法
CGLib和JDKProxy的实现方法比较类似,都是实现代理器的接口
再调用某一方法,实现动态代理
唯一不同:
CGLib在初始化被代理类时,是通过Enhancer对象把被代理对象设置为代理类的子类,来实现动态代理的功能,因此被代理类不能被设置为final
Lombok是通过反射实现的吗
属于Java的一个热门工具类
使用它可以有效的解决代码工程中那些繁琐又重复的代码(getter/setter,toString,equals,hashCode等方法)
在类上加@Data可以自动代理出上述的方法。
Lombok的实现和反射没有任何关系
反射是程序在运行期的一种自省(introspect)能力
Lombok的实现是在编译期完成的
Lombok是基于java1.6实现的JSR-269(Pluggable Annotation Processing API(插件式注解处理器))
编码器自定义注解处理器实现的
当Java将源码抽象成AST之后,Lombok会根据注解动态的修改AST增加新的代码,生成最终的源码
动态代理和静态代理有什么区别
静态代理其实就是事先写好代理类,可以手工编写,也可以工具生成
他的缺点是每个业务类都要有一个对应的代理类,不灵活,不方便,所以产生了动态代理
动态代理的使用场景有哪些
RPC框架的封装,AOP的实现,JDBC的链接等
Spring中的动态代理是通过什么方式实现的
同时使用了JDK Proxy和CGLib
当bean实现了接口的时候,默认使用JDK Proxy
没有的时候,默认使用CGLib
我们也可以强制使用CGLib
只需要在Spring配置中添加
<aop:aspectj-autoproxt proxy-target-class="true" />
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- codeforces 1374E1(贪心+优先队列)
- codeforces 455A(dp)
- codeforces 1296E1(贪心+思维)
- codeforces 1216E1(数学+暴力)
- JDBC基础入门使用
- codeforces 1353E(dp)
- codeforces 1396A(构造)
- codeforces 1335E1+E2(思维)
- JSP开发基础入门学习1
- codeforces 1407C(数学+交互题)
- codeforces 1420C1
- codeforces 1417D(思维,构造)
- Servlet基础入门学习2
- codeforces 1426D(思维)
- codeforces 1324E(dp)