Spring中的两种代理JDK和CGLIB的区别浅谈
发布时间 - 2026-01-11 00:30:46 点击率:次一、原理区别:

Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP?
(1)添加CGLIB库,SPRING_HOME/cglib/.jar
(2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK动态代理和CGLIB字节码生成的区别?
(1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
二、代码实现
package com.fy.spring.proxy;
public interface UserManager {
public void addUser(String id, String password);
public void delUser(String id);
}
package com.fy.spring.proxy;
public class UserManagerImpl implements UserManager {
public void addUser(String id, String password) {
System.out.println(".: 掉用了UserManagerImpl.addUser()方法! ");
}
public void delUser(String id) {
System.out.println(".: 掉用了UserManagerImpl.delUser()方法! ");
}
}
JDK动态代理类
package com.fy.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* 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);//返回代理对象
}
public Object invoke(Object proxy, Method method, Object[] args)//invoke方法
throws Throwable {
checkPopedom();//一般我们进行逻辑处理的函数比如这个地方是模拟检查权限
Object ret = null; // 设置方法的返回值
ret = method.invoke(targetObject, args); //调用invoke方法,ret存储该方法的返回值
return ret;
}
private void checkPopedom() {//模拟检查权限的例子
System.out.println(".:检查权限 checkPopedom()!");
}
}
CGLibProxy动态代理类
package com.fy.spring.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* CGLibProxy动态代理类的实例
*
*
*/ public class CGLibProxy implements MethodInterceptor {
private Object targetObject;// CGLib需要代理的目标对象
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;// 返回代理对象
}
public 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 Client {
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 jdkPrpxy = new JDKProxy();
UserManager userManagerJDK = (UserManager) jdkPrpxy
.newProxy(new UserManagerImpl());
userManagerJDK.addUser("tom", "root");
}
}
运行结果:
-----------CGLibProxy-------------
检查权限 checkPopedom()!
掉用了UserManagerImpl.addUser()方法!
-----------JDKProxy-------------
检查权限 checkPopedom()!
掉用了UserManagerImpl.addUser()方法!
JDK代理是不需要以来第三方的库,只要要JDK环境就可以进行代理,它有几个要求
- 实现InvocationHandler
- 使用Proxy.newProxyInstance产生代理对象
- 被代理的对象必须要实现接口
CGLib 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承但是针对接口编程的环境下推荐使用JDK的代理
在Hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的相关代理采用的是CGLib来执行。
希望本文所述对你有所帮助,Spring中的两种代理JDK和CGLIB的区别浅谈内容就给大家介绍到这里了。希望大家继续关注我们的网站!想要学习java可以继续关注本站。
# spring
# cglib
# jdk
# jdk动态代理
# Java JDK与cglib动态代理有什么区别
# 详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理
# 基于jdk动态代理和cglib动态代理实现及区别说明
# 用了
# 子类
# 的是
# 实现了
# 不需要
# 返回值
# 是一种
# 两种
# 推荐使用
# 对你
# 考虑到
# 有几个
# 希望大家
# 第三方
# 浅谈
# 来实现
# 能对
# 就给
# 所述
# 开源
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel如何优化应用性能?(缓存和优化命令)
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
php485函数参数是什么意思_php485各参数详细说明【介绍】
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
如何在万网主机上快速搭建网站?
如何在服务器上配置二级域名建站?
JS去除重复并统计数量的实现方法
如何在腾讯云服务器快速搭建个人网站?
JavaScript如何实现类型判断_typeof和instanceof有什么区别
实例解析angularjs的filter过滤器
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Win11关机界面怎么改_Win11自定义关机画面设置【工具】
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
高端企业智能建站程序:SEO优化与响应式模板定制开发
BootStrap整体框架之基础布局组件
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
公司网站制作需要多少钱,找人做公司网站需要多少钱?
如何在Windows服务器上快速搭建网站?
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
🚀拖拽式CMS建站能否实现高效与个性化并存?
Laravel如何处理异常和错误?(Handler示例)
,怎么在广州志愿者网站注册?
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
如何用花生壳三步快速搭建专属网站?
Internet Explorer官网直接进入 IE浏览器在线体验版网址
Laravel如何使用模型观察者?(Observer代码示例)
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
如何利用DOS批处理实现定时关机操作详解
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
PythonWeb开发入门教程_Flask快速构建Web应用
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
黑客如何通过漏洞一步步攻陷网站服务器?
如何用景安虚拟主机手机版绑定域名建站?
phpredis提高消息队列的实时性方法(推荐)
如何挑选高效建站主机与优质域名?
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
零基础网站服务器架设实战:轻量应用与域名解析配置指南
如何在Tomcat中配置并部署网站项目?
C++时间戳转换成日期时间的步骤和示例代码
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
Laravel模型事件有哪些_Laravel Model Event生命周期详解
Laravel定时任务怎么设置_Laravel Crontab调度器配置

