当前位置: 首页 > news >正文

Java 动态代理实现

Java 动态代理实现

  • 一、JDK动态代理
  • 二、CGLIB动态代理
  • 三、动态代理的应用场景
  • 四、JDK代理与CGLIB代理比较

动态代理是Java中一种强大的技术,它允许在运行时创建代理对象,用于拦截对目标对象的方法调用。

一、JDK动态代理

JDK动态代理是Java标准库提供的代理实现,基于接口。

  1. 定义接口
interface UserService {void addUser(String name);
}
  1. 实现接口
class UserServiceImpl implements UserService {@Overridepublic void addUser(String name) {System.out.println("添加用户" + name);}
}
  1. 实现InvocationHandler
class UserServiceInvocationHandler implements InvocationHandler {private Object target;public UserServiceInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("--- 前置处理 ---");Object result = method.invoke(target, args);System.out.println("--- 后置处理 ---");return result;}
}
  1. 创建代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JdkProxyDemo {public static void main(String[] args) {UserService userService = new UserServiceImpl();UserServiceInvocationHandler invocationHandler = new UserServiceInvocationHandler(userService);UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),userService.getClass().getInterfaces(), invocationHandler);proxy.addUser("张三");}
}

jdk

二、CGLIB动态代理

当目标类没有实现接口时,可以使用CGLIB库实现动态代理。

  1. 添加CGLIB依赖(Maven)
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
  1. 目标类(不需要实现接口)
class ProductService {public void addProduct(String name) {System.out.println("添加产品: " + name);}
}
  1. 方法拦截器
class ProductMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("--- 前置处理 ---");// 调用父类方法Object result = proxy.invokeSuper(obj, args);System.out.println("--- 后置处理 ---");return result;}
}
  1. 创建代理
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class CglibProxyDemo {public static void main(String[] args) {ProductMethodInterceptor interceptor = new ProductMethodInterceptor();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(ProductService.class);enhancer.setCallback(interceptor);ProductService proxy = (ProductService) enhancer.create();proxy.addProduct("手机");}
}

cglib

三、动态代理的应用场景

  1. AOP编程:如Spring的AOP功能
  2. 远程方法调用:如RPC框架
  3. 事务管理
  4. 日志记录
  5. 权限控制
  6. 性能监控

四、JDK代理与CGLIB代理比较

特性JDK动态代理CGLIB动态代理
基于接口
性能创建快,运行慢创建慢,运行快
限制只能代理接口不能代理final类和方法
依赖Java内置需要第三方库
实现原理反射字节码生成

在Spring框架中,如果目标对象实现了接口,默认使用JDK动态代理,否则使用CGLIB代理。

相关文章:

  • webgl入门实例-向量在图形学中的核心作用
  • 【每日八股】复习计算机网络 Day2:TCP 断开连接时四次挥手及其相关问题
  • [Java实战经验]异常处理最佳实践
  • opencv--图像处理
  • Vue3 + TypeScript中defineEmits 类型定义解析
  • LeetCode 5:最长回文子串
  • 【java实现+4种变体完整例子】排序算法中【冒泡排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
  • AI写代码工具分享:Cursor 高效使用攻略与实战秘籍
  • 【图片识别分类】如何快速识别照片中的水印文字,对图片进行关键字分类,快速整理水印相机拍摄图片,基于WPF和腾讯OCR的技术实现
  • QML中的3D功能--自定义着色器开发
  • 实现Azure Synapse Analytics安全地请求企业内部API返回数据
  • Flink框架十大应用场景
  • 嵌入式软件--stm32 DAY 2
  • 为什么浮点数会搞出Infinity和NAN两种类型?浮点数的底层原理?IEEE 754标准揭秘?
  • VSCode安装与环境配置(Mac环境)
  • 【计算机视觉】CV实战项目- Face-and-Emotion-Recognition 人脸情绪识别
  • sqlilabs-Less11 POST注入
  • 一个项目中多个Composer的使用方法
  • LibModbus 主从机通信应用实例
  • 【今日三题】判断是不是平衡二叉树(递归) / 最大子矩阵(二维前缀和) / 小葱的01串(滑动窗口)
  • 两大跨国巨头称霸GLP-1市场,国产减肥药的机会在哪?
  • 习近平主席东南亚三国行|元首外交硕果累累 • 一图读懂
  • 习近平会见柬埔寨太后莫尼列
  • 2025年中国航天工程有哪些重点任务?国家航天局介绍
  • 陈少洋出任中国航天科工集团党组副书记、董事、总经理
  • 铁路12306开始发售5月1日车票,系统保持安全平稳运行