设计模式--CGLib动态代理的实现与解析
来源:互联网 发布:百度php面试题 编辑:程序博客网 时间:2024/06/11 20:08
在前两篇的JDK动态代理中,它是通过Proxy类和实现InvocationHandler接口实现的。但是此方式最大的缺点是:要求被代理的目标类必须实现一个接口,而且只能对接口中的方法实现代理。因为最终生成的代理类是继承了Proxy类以及实现了目标类的接口。
如果被代理的目标类没有实现接口,JDK就无法完成代理。这时,可以采用CGLib动态代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
Cglib是一个强大的,高性能,高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。大部分功能实际上是ASM所提供的,Cglib只是封装了ASM,简化了ASM操作,实现了运行期生成新的class。CGLib在运行时动态的生成一个被代理类的子类(通过ASM字节码处理框架实现),子类重写了被代理类中所有非final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势植入横切逻辑。
拦截器:实现MethodInterceptor接口的类,在intercept方法中实现对代理目标类的方法拦截。
Enhancer类,来生成代理类。
CGLib动态代理实现:
先看如何实现:
目标类(被委托类)
package com.blog.cglibproxy;/** * @Description: * @Author: Jingzeng Wang * @Date: Created in 16:01 2017/6/27. */public class UserDao { /** * 目标类的add方法 */ public void add() { System.out.println("目标类的添加方法!!"); } /** * 目标类的delete方法 */ public void delete() { System.out.println("目标类的删除方法!!"); }}
代理逻辑,实现了MethodInterceptor 的intercept()方法:
package com.blog.cglibproxy;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/** * @Description: 代理逻辑 * @Author: Jingzeng Wang * @Date: Created in 17:12 2017/6/27. */public class MyInterceptor implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz) { //设置目标类 enhancer.setSuperclass(clazz); //设置拦截实现类 enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //横切逻辑 System.out.println("-------------------before-----------------"); //委托类方法 Object result = methodProxy.invokeSuper(o, objects); System.out.println("-------------------after------------------"); return result; }}
测试类:
package com.blog.cglibproxy;/** * @Description: * @Author: Jingzeng Wang * @Date: Created in 17:19 2017/6/27. */public class Test { public static void main(String[] args) { MyInterceptor myInterceptor = new MyInterceptor(); UserDao proxy = (UserDao) myInterceptor.getProxy(UserDao.class); proxy.add(); proxy.delete(); }}
其结果为:
-------------------before-----------------目标类的添加方法!!-------------------after-------------------------------------before-----------------目标类的删除方法!!-------------------after------------------
这就实现了对目标类的代理。生成的代理类是直接操作字节码继承了目标类。
CGLib动态代理与JDK动态代理的区别
CGLib主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态
- 设计模式--CGLib动态代理的实现与解析
- 基于cglib实现的动态代理原理与源码解析
- 设计模式--动态代理(CGLIB)
- Cglib动态代理模式实现
- Java 动态代理的理解与Cglib动态代理实现
- 代理模式之动态代理的实现——CGLib
- Java设计模式--代理模式与JDK动态代理,cglib动态代理
- 系统架构设计——设计模式之代理模式(二)CGLIB动态代理实现
- CGLIB 动态代理的实现
- java 代理模式 CGLIB的动态代理
- 设计模式学习之代理模式(二)--CGLIB实现对Class动态代理
- 设计模式--JDK动态代理的实现与原理解析(1)
- 设计模式--JDK动态代理的实现与原理解析(2)
- 代理模式--JDK动态代理与CGLIB动态代理的区别
- cglib动态代理模式
- cglib动态代理模式
- 代理设计模式(JDK与CGLIB)
- 代理模式-cglib动态代理
- ActiveMQ集群:网络连接模式(network connector)详解 .
- HDU 4689 Derangement【DP递推】【好题】【思维题】
- 2. 线性结构--栈
- tensorflow1.1/线性回归
- 建立自己的Github Repository
- 设计模式--CGLib动态代理的实现与解析
- Android MPChart 可跨屏幕可滑动 扩展项目 OpenCodeMpSiChart
- 浅谈JavaScript之DOM
- 逻辑设计中多时钟设计【1】
- 利用jsoup的选择器语法来查找元素
- 你该关注“硬技术”还是“大道理”呢?
- 计算机网络札记
- 无法推送一些引用到 'git@github.com:Apologise/DjangoSample.git' 提示:更新被拒绝,因为远程仓库包含您本地尚不存在的提交。这通常是因为另外 提示:一个仓库已向
- 2017.6.29 学习记录 结构控制语言