动态代理的两种方式以及区别
JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler
来处理。
CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。
强制使用CGlib
<!-- proxy-target-class="false"默认使用JDK动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/><aop-config proxy-target-class="true">
具体代码示例:
/*** 目标接口类*/
public interface UserManager { public void addUser(String id, String password); public void delUser(String id);
}
/*** 接口实现类*/
public class UserManagerImpl implements UserManager { @Overridepublic void addUser(String id, String password) { System.out.println("调用了UserManagerImpl.addUser()方法!");} @Overridepublic void delUser(String id) { System.out.println("调用了UserManagerImpl.delUser()方法!");}
}
/*** JDK动态代理类*/
public class JDKProxy implements InvocationHandler { // 需要代理的目标对象private Object targetObject; public Object newProxy(Object targetObject) {// 将目标对象传入进行代理 this.targetObject = targetObject;// 返回代理对象 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);} // invoke方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 进行逻辑处理的函数checkPopedom();Object ret = null;// 调用invoke方法ret = method.invoke(targetObject, args);return ret;} private void checkPopedom() {// 模拟检查权限 System.out.println("检查权限:checkPopedom()!"); }
}
/*** CGlib动态代理类*/public class CGLibProxy implements MethodInterceptor { // CGlib需要代理的目标对象private Object targetObject;public Object createProxyObject(Object obj) {this.targetObject = obj;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(obj.getClass());enhancer.setCallback(this);Object proxyObj = enhancer.create();return proxyObj;}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object obj = null;// 过滤方法if ("addUser".equals(method.getName())) {// 检查权限checkPopedom();}obj = method.invoke(targetObject, args);return obj;} private void checkPopedom() {System.out.println("检查权限:checkPopedom()!");}
}
/*** 测试类*/
public class ProxyTest {public static void main(String[] args) {UserManager userManager = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());System.out.println("CGLibProxy:");userManager.addUser("tom", "root");System.out.println("JDKProxy:");JDKProxy jdkProxy = new JDKProxy();UserManager userManagerJDK = (UserManager)jdkProxy.newProxy(new UserManagerImpl());userManagerJDK.addUser("tom", "root");}
}
// 运行结果
CGLibProxy:
检查权限checkPopedom()!
调用了UserManagerImpl.addUser()方法!
JDKProxy:
检查权限checkPopedom()!
掉用了UserManagerImpl.addUser()方法!
总结:
- JDK代理使用的是反射机制实现aop的动态代理,CGLIB代理使用字节码处理框架asm,通过修改字节码生成子类。所以jdk动态代理的方式创建代理对象效率较高,执行效率较低,cglib创建效率较低,执行效率高;
- JDK动态代理机制是委托机制,具体说动态实现接口类,在动态生成的实现类里面委托hanlder去调用原始实现类方法,CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。
动态代理的两种方式以及区别相关推荐
- spring中AOP动态代理的两种方式
AOP动态代理的两种方式 Spring AOP动态代理的方式(spring的AOP默认是JDK Proxy) 浅谈这两种动态代理 JDK的动态代理,需要有实现接口 动态代理--JDK Proxy ⚫ ...
- Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别
视频功能审核通过了,可以看视频啦!记得点关注啊~ 注意:因为网络原因,视频前一两分钟可能会比较模糊,过一会儿就好了 记得点关注啊,视频里的wx二维码失效了,wx搜索:"聊5毛钱的java&q ...
- 动态代理的两种方式_动态代理是基于什么原理?
代理模式 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问. 什么是动态代理 运行时动态生成代理类. 动态代理我们需要些什么 1.业务接口(Interface) 业务的抽象表示. 2.业务 ...
- Java实现动态代理的两种方式
http://m.blog.csdn.net/article/details?id=49738887
- SpringAop动态代理的两种实现方式
Spring的面向切面编程也是基于动态代理来实现的 静态代理:也就是自己手动创建的代理对象 动态代理:也就是在程序运行中通过配置参生的 那么Spring的AOP也就是面向切面编程,就是基于动态代理来实 ...
- Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理 代理模式 JDK动态代理 CGLIB动态代理 代理模式 代理模式是23种设计模式的一种,指一个对象A通过持有另一个对象B,可以具有B ...
- vue 路由传参 params 与 query两种方式的区别(转载)
vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了: ro ...
- Java动态代理的两种实现方法
转载自 http://blog.csdn.net/HEYUTAO007/article/details/49738887 AOP的拦截功能是由java中的动态代理来实现的.说白了,就是在目标类的基础上 ...
- java两种绑定方式_Javascript绑定事件的两种方式的区别
命名函数 function check(){ //code } 匿名函数 window.onload = function(){ //先获取元素对象,再绑定事件,绑定的是匿名函数不可重用 var bt ...
- vue 路由传参 params 与 query两种方式的区别
vue 路由传参 params 与 query两种方式的区别 初学vue的时候,不知道如何在方法中跳转界面并传参,百度过后,了解到两种方式,params 与 query.然后,错误就这么来了: ro ...
最新文章
- CMOS图像传感器理解
- python中字符串(比如文件路径)前面有一个r什么意思
- 深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor...
- 请解释和、|和||的区别?
- IPC\DVS\DVR与NVR之间的区别
- I/O复用函数的使用——select
- 大厂产品是如何做行业调研和规划的?附汇报模版(PPT)
- 深度剖析WinPcap之(二)——网络分析与嗅探的基础知识(4)
- 【干货】31篇关于深度学习必读论文汇总(附论文下载地址)
- 游戏开发之动态创建对象及构造函数、析构函数的执行(C++基础)
- java 圣思园视频资源
- python的invalid syntax是什么意思_请问在python 中 出现 invalid syntax 是什么意思 ?
- 计算机用户删除 cmd,命令提示符下怎么新建用户和删除用户
- sql server的元素类型int identity(1,1)是什么意思?
- zabbix 主动监控与被动监控
- Java Online IDE
- 如何用python完成评分功能呢_Python:豆瓣电影评分
- HCIP之OSPF(五)
- 好未来赚数倍,大跌前又精准提前离场:高瓴张磊的核心投资方法论到底是什么?
- 剔除半角字符和空格 java_去掉字符串中的全角,半角空格,回车,制表符