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

动态代理 设计模式

JDK 动态代理的核心实现公式可以提取为以下结构,主要包含 3 个关键部分:

  1. 代理对象创建(Proxy.newProxyInstance()
  2. 类加载器与接口指定
  3. InvocationHandler 匿名实现(增强逻辑)

核心要素解析:

  1. 三参数固定写法

    • 类加载器:target.getClass().getClassLoader()
    • 接口数组:target.getClass().getInterfaces()
    • 处理器:new InvocationHandler() { ... }
  2. 增强逻辑固定结构

    try {// 前置增强// 执行目标方法// 后置增强
    } catch (Exception e) {// 异常增强
    } finally {// 最终增强
    }
    
  3. 核心方法

    • Proxy.newProxyInstance():创建代理对象的入口
    • method.invoke(target, args):反射调用目标对象的方法

动态代理类

  return Proxy.newProxyInstance(classLoader, interfaces, handler);

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** JDK动态代理通用模板*/
public class DynamicProxyTemplate {// 获取目标对象的代理对象public static Object getProxyInstance(Object target) {// 1. 类加载器:使用目标对象的类加载器ClassLoader classLoader = target.getClass().getClassLoader();// 2. 接口数组:目标对象实现的所有接口Class<?>[] interfaces = target.getClass().getInterfaces();// 3. 增强逻辑:InvocationHandler匿名实现InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;try {// 前置增强:方法执行前的逻辑beforeEnhance(method, args);// 执行目标方法(核心业务逻辑)result = method.invoke(target, args);// 后置增强:方法正常返回后的逻辑afterReturnEnhance(method, result);} catch (Exception e) {// 异常增强:方法抛出异常时的逻辑exceptionEnhance(method, e);} finally {// 最终增强:无论是否异常都会执行的逻辑finallyEnhance(method);}return result;}};// 创建并返回代理对象return Proxy.newProxyInstance(classLoader, interfaces, handler);}// 前置增强(示例方法)private static void beforeEnhance(Method method, Object[] args) {System.out.println("方法[" + method.getName() + "]执行前,参数:" + Arrays.toString(args));}// 后置返回增强(示例方法)private static void afterReturnEnhance(Method method, Object result) {System.out.println("方法[" + method.getName() + "]执行完成,返回值:" + result);}// 异常增强(示例方法)private static void exceptionEnhance(Method method, Exception e) {System.out.println("方法[" + method.getName() + "]执行异常:" + e.getMessage());}// 最终增强(示例方法)private static void finallyEnhance(Method method) {System.out.println("方法[" + method.getName() + "]执行结束");}
}

package com.atguigu.spring.aop.proxy.dynamic;import com.atguigu.spring.aop.log.LogUtils;import java.lang.reflect.Proxy;
import java.util.Arrays;/*** 动态代理: JDK动态代理;* 强制要求,目标对象必有接口。代理的也只是接口规定的方法。**/
public class DynamicProxy {//获取目标对象的代理对象public static Object getProxyInstance(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) -> {String name = method.getName();//记录开始LogUtils.logStart(name, args);Object result = null;try{result = method.invoke(target, args);//记录返回值LogUtils.logReturn(name, result);}catch (Exception e){//记录异常LogUtils.logException(name, e);}finally {//记录结束LogUtils.logEnd(name);}return result;});}
}

不需要单独写类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;// 1. 定义接口
interface Calculator {int add(int a, int b);
}// 2. 实现接口的目标类
class MyCalculator implements Calculator {@Overridepublic int add(int a, int b) {return a + b;}
}public class DynamicProxyDemo {public static void main(String[] args) {// 目标对象Calculator target = new MyCalculator();// 直接创建代理对象(无需单独编写代理类)Calculator proxy = (Calculator) Proxy.newProxyInstance(target.getClass().getClassLoader(),  // 类加载器target.getClass().getInterfaces(),   // 接口数组new InvocationHandler() {            // 匿名内部类实现增强逻辑@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法[" + method.getName() + "]开始,参数:" + Arrays.toString(args));// 调用目标方法Object result = method.invoke(target, args);System.out.println("方法[" + method.getName() + "]结束,结果:" + result);return result;}});// 测试代理对象proxy.add(10, 20);}
}

http://www.dtcms.com/a/389233.html

相关文章:

  • APP小程序被攻击了该如何应对
  • 零基础从头教学Linux(Day 37)
  • ADB 在嵌入式 Linux 系统调试中的应用
  • 7HTMLCSS高级
  • 玩游戏/用设计软件提示d3dcompiler_47.dll缺失怎么修复?5步快速定位问题,高效修复不踩坑
  • HTML应用指南:利用GET请求获取全国宝马授权经销商门店位置信息
  • 《Java网络编程》第一章:基本网络概念
  • Python内存机制全解析:从基础到高级应用
  • Ubuntu24修改ssh端口
  • hadoop实现一个序列化案例
  • DBG数据库加密网关实现mySQL敏感数据动态脱敏与加密全攻略
  • 解决 Vue SPA 刷新导致 404 的问题
  • 大型语言模型 (LLMs) 的演进历程:从架构革命到智能涌现
  • 大语言模型为什么要叫【模型】
  • 教程上新丨ACL机器翻译大赛30个语种摘冠,腾讯Hunyuan-MT-7B支持33种语言翻译
  • 《C++程序设计》笔记
  • NVR接入录像回放平台EasyCVR海康设备视频平台视频监控系统常见故障与排查全解析
  • 半导体制造常提到的Fan-Out晶圆级封装是什么?
  • Qt 系统相关 - 文件
  • P2242 公路维修问题
  • 安装wsl
  • 牛客多校04C :Computational Geometry Problem(p-Dyck路计数)
  • CMake+visual studio 2022 +qt6 , 从Linux平台移植到windows下平台开发
  • 大模型系列——Playwright MCP 可以复用 Chrome 登录态了
  • 三星S25 Edge 与iPhone 17 Air:最新对比
  • 电脑怎么连接wifi?【图文详解】笔记本电脑怎么连接无线wifi?笔记本电脑连不上wifi怎么办?
  • 设计模式-代理模式详解
  • 怎样让AI图生3D更加高质高效
  • Java 集合框架 Set 接口:实现类的底层数据结构与核心特点
  • 【大模型】使用Qwen-VL大模型进行验证码识别的完整指南