【Java深入研究】6、CGLib动态代理机制详解
一、首先说一下JDK中的动态代理:
JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的
但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高。
二、使用CGLib实现:
使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
下面,将通过一个实例介绍使用CGLib实现动态代理。
1、被代理类:
首先,定义一个类,该类没有实现任何接口,包含两个方法。
- public class ConcreteClassNoInterface {
- public String getConcreteMethodA(String str){
- System.out.println("ConcreteMethod A ... "+str);
- return str;
- }
- public int getConcreteMethodB(int n){
- System.out.println("ConcreteMethod B ... "+n);
- return n+10;
- }
- }
2、拦截器:
定义一个拦截器。在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。
- public class ConcreteClassInterceptor implements MethodInterceptor{
- public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
- System.out.println("Before:"+method);
- Object object=proxy.invokeSuper(obj, arg);
- System.out.println("After:"+method);
- return object;
- }
- }
参数:Object为由CGLib动态生成的代理类实例,Method为上文中实体类所调用的被代理的方法引用,Object[]为参数值列表,MethodProxy为生成的代理类对方法的代理引用。
返回:从代理实例的方法调用返回的值。
其中,proxy.invokeSuper(obj,arg):
调用代理类实例上的proxy方法的父类方法(即实体类ConcreteClassNoInterface中对应的方法)
在这个示例中,只在调用被代理类方法前后各打印了一句话,当然实际编程中可以是其它复杂逻辑。
3、生成动态代理类:
- Enhancer enhancer=new Enhancer();
- enhancer.setSuperclass(ConcreteClassNoInterface.class);
- enhancer.setCallback(new ConcreteClassInterceptor());
- ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create();
这里Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展,以后会经常看到它。
首先将被代理类ConcreteClassNoInterface设置成父类,然后设置拦截器ConcreteClassInterceptor,最后执行enhancer.create()动态生成一个代理类,并从Object强制转型成父类型ConcreteClassNoInterface。
最后,在代理类上调用方法:
- ccni.getConcreteMethodA("shensy");
- ccni.getConcreteMethodB(0);
查看控制台输出:
- Before :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)
- ConcreteMethod A ... shensy
- After :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)
- Before :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)
- ConcreteMethod B ... 0
- After :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)
可以看到,拦截器在调用被代理类方法前后都执行了print操作。
转自:http://shensy.iteye.com/blog/1873155
【Java深入研究】6、CGLib动态代理机制详解的更多相关文章
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- 【转】java的动态代理机制详解
java的动态代理机制详解 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们 ...
- java的动态代理机制详解-----https://www.cnblogs.com/xiaoluo501395377/p/3383130.html
java的动态代理机制详解-----https://www.cnblogs.com/xiaoluo501395377/p/3383130.html
- Spring源码剖析5:JDK和cglib动态代理原理详解
AOP的基础是Java动态代理,了解和使用两种动态代理能让我们更好地理解 AOP,在讲解AOP之前,让我们先来看看Java动态代理的使用方式以及底层实现原理. 转自https://www.jiansh ...
- 【Java深入研究】5、Proxy动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- Java 动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- java的动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- Java的动态代理机制详解(转)
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- (转)java的动态代理机制详解
原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一 ...
随机推荐
- 设计一个BCD码计数器。
BCD码计数器的定义: 对于机器语言,机器与人不同,为了让人更好的了解机器语言的数据输出,选用4位二进制数据表示十进制里的每位数据,这便是BCD码. 以下便是BCD码与十进制对应的码表 0------ ...
- 初识Twisted(一)
pip install Twisted 安装Twisted库 from twisted.internet import reactor #开启事件循环 #不是简单的循环 #不会带来任何性能损失 rea ...
- Java 中的 HttpServletRequest 和 HttpServletResponse 对象
HttpServletRequest对象详解 javax.servlet.http.HttpServletRequest是SUN制定的Servlet规范,是一个接口.表示请求,“HTTP请求协议”的完 ...
- Origin的使用问题集锦
在空间上看见同学转的一篇关于学术研究的文章,由于不常常上空间,更别说在上面看一些好的文章,所以特意将那篇文章整理到自己的博客中,方便以后做科研的时候能够用到,原文出处:http://user.qzon ...
- Django Rest Swagger生成api文档
关于swagger Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因: Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API. Sw ...
- CSS基础和选择器
什么是CSS? CSS是指层叠样式表(Cascading Style Sheets),样式定义如何显示HTML元素,样式通常又会存在于样式表中.也就是说把HTML元素的样式都统一收集起来写在一个地方或 ...
- HW2017笔试编程题
一.写一个转换字符串的函数 1.题目描述 将输入字符串中下标为偶数的字符连成一个新的字符串输出,需要注意两点: (1)如果输入字符串的长度超过20,则转换失败,返回“ERROR!”字符串: (2)输入 ...
- 【Promise】Promise实现请求超时处理(加强版)
昨天闲来无事,于是把之前写过的promise优化了一下,代码如下: /*写文件.追加写.读文件*/ var fs = require('fs'); function wrapper(fn,contex ...
- 从零开始学 Web 之 JavaScript 高级(一)原型,贪吃蛇案例
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- await和async在一般处理程序中的使用
写在前面 有个小项目,前端使用的html页面,那服务端的业务处理就采用最简单的一般处理程序了,之前一直在用,觉得一直用一种方式,确实挺蛋疼的,之前也有了解过async和await的内容.就想着自己折腾 ...