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

动态代理代码示例

理解动态代理

  1. 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的,而不是在编译时就已经确定的
  2. 性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强
  3. 为什么JDK动态代理只能代理有接口的类?
  • 因为Proxy.newProxyInstance方法需要传入被动态代理的接口类target.getClass().getInterfaces(),之所以要传入接口而不能传入类,因为JDK动态代理会在运行时生成一个代理类,叫做$Proxy0,这个代理类会继承java.lang.reflect.Proxy这个类,同时还会去实现被代理类的接口,在Java里面是不支持多继承的,而每一个动态代理类都继承了一个Proxy,所以就导致了JDK动态代理只能代理接口,而不能代理实现类
  • 其实也可以进行实现类的代理,但是代理接口的设计更符合业务场景,因为实际的开发中都是面向接口来开发的,所以基于接口来实现动态代理更符合业务场景

JDK动态代理

public interface Service {void doSomething();
}public class ServiceImpl implements Service {@Overridepublic void doSomething() {System.out.println("Doing something");}
}import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** JDK动态代理示例*/
public class MyInvocationHandler implements InvocationHandler {// target在构造之后不会发生改变private final Object target;public MyInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置处理");Object object = method.invoke(target, args);System.out.println("后置处理");return object;}// 调用此方法,会返回一个实现了目标对象所有接口的代理对象,这个代理对象会使用当前类作为InvocationHandlerpublic Object getProxy() {// 类加载器、接口数组、InvocationHandlerreturn Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);}}public static void main(String[] args) {// 创建真实的服务对象Service realService = new ServiceImpl();// 创建 MyInvocationHandler 的实例,并传入真实的服务对象MyInvocationHandler handler = new MyInvocationHandler(realService);// 使用 MyInvocationHandler 创建代理对象Service proxy = (Service) handler.getProxy();// 调用代理对象的方法proxy.doSomething();}

CGlib动态代理

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.5</version></dependency>

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;/*** 适用于没有实现任何接口的类* 需要引入cglib代码库* cglib增强器,负责拦截方法调用,并添加额外逻辑*/
public class CGlibProxy implements MethodInterceptor {public Object createProxy(Object target) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create(); // 动态创建代理对象}@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;}
}public static void main(String[] args) {ServiceImpl service = new ServiceImpl();CGlibProxy proxy = new CGlibProxy();ServiceImpl proxyService = (ServiceImpl) proxy.createProxy(service);proxyService.doSomething();}
http://www.lryc.cn/news/456112.html

相关文章:

  • SpringBoot+Activiti7工作流使用进阶实例-高亮显示BPMN流程图( SpringBoot+Activiti+mybatis+shiro实现)
  • C#使用Lazy<T>提高性能
  • 创建读取比特币1P类型地址
  • 从零开始Hadoop集群环境搭建
  • Copley耐环境伺服驱动器 极端环境下高精度控制解决方案
  • 前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析
  • 基于Zynq SDIO WiFi移植一(支持2.4/5G)
  • 数据结构与算法篇(刷题篇 - 链表)
  • TinyAgent: 从零开始构建最小化Agent系统
  • Android Studio New里面没有New Flutter Project
  • linux信号 | 学习信号四步走 | 透析信号是如何被处理的?
  • mysql语句执行过程
  • 最新版本SkyWalking【10.1.0】部署
  • WSL2 中配置桥接模式、虚拟交换机及固定 IP
  • Unite Shanghai 2024 团结引擎专场 | 团结引擎 OpenHarmony 工程剖析
  • 计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python毕业设计 Python毕业设计选题 Spark 大数据【附源码+安装调试】
  • 2022CCPC绵阳站VP题解报告(CGHMAE六题)
  • 代码随想录day23:贪心part1
  • 通过网页设置参数,submit还是json
  • C语言 | Leetcode C语言题解之第463题岛屿的周长
  • 逼近理论及应用精解【12】
  • LIN总线学习大全(基于CANoe和CAPL)
  • 国庆作业
  • Android OpenGLES2.0开发(四):矩阵变换和相机投影
  • 快递查询软件:实现单号识别与批量物流查询的高效工具
  • nodejs与npm版本对应表
  • Spring Boot 项目中如何使用异步任务
  • Scrum实战中遇到的问题与解决方法
  • 全面介绍 Windows 录屏工具:开启录制新篇章
  • Maven 和 NetBeans:集成与使用