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

Java静态代理与动态代理实战解析

Java静态代理

示例代码

接口:

package com.ssg.aop.interfaces;public interface MathCalculator {
//    加法public int add(int a, int b);
}

接口实现类:

package com.ssg.aop.impl;
import com.ssg.aop.interfaces.MathCalculator;public class MathCalculatorImpl implements MathCalculator {@Overridepublic int add(int a, int b) {int i = a + b;System.out.println("方法执行结果 = " + i);return i;}
}

静态代理类:

  • 静态代理类继承接口文件,重写方法
  • 静态代理类通过构造器来引入原代理类。
package com.ssg.aop.proxy.statics;
import com.ssg.aop.interfaces.MathCalculator;public class MathCalculatorStaticProxy implements MathCalculator {//    接口倒置,注入接口,而不是实现类private MathCalculator mathCalculator;public MathCalculatorStaticProxy(MathCalculator mathCalculator) {this.mathCalculator = mathCalculator;}/*** @param a* @param b* @return*/@Overridepublic int add(int a, int b) {System.out.println("开始 >>> a + b == " + a + "+" + b);int add = mathCalculator.add(a, b);System.out.println("结束 >>> a + b = " + add);return add;}
}

@Test测试类

public class TestMathCalculator {@Testpublic void testAdd() {MathCalculator mathCalculatorImpl = new MathCalculatorImpl();MathCalculator calculator = new MathCalculatorStaticProxy(mathCalculatorImpl);int result = calculator.add(1, 2);System.out.println("Test add result = " + result);}
}

Java原生动态代理

Java原生动态代理,缺点是:代理对象必须是接口,没有接口无法代理。为所有方法进行代理,不能灵活操控。

示例代码

接口文件、接口实现类、动态代理类、Test类。

接口和接口实现类

沿用静态代理中的接口和接口实现类。

动态代理类:

写法一

核心:类加载器、类接口、InvocationHandler逻辑类其作用为:动态代理的具体逻辑代码写在该处。

Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);

package com.ssg.aop.proxy.dynamic;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;public class MathCalculatorDynamicProxy {public static Object getDynamicProxy(Object object) {// object:目标对象,被代理的对象// 第一个参数:需要类加载器,通过反射获取// 第二个参数:需要获取类接口(被代理对象的接口)信息,通过反射// 第三个对象:代理逻辑,怎么去代理return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("动态代理执行前:" + Arrays.toString(args));Object invoke = method.invoke(object, args);System.out.println("动态代理执行后:" + invoke.toString());return invoke;}});}
}
写法二:
    /*** 动态代理,代理所有类方法* @param mathClass 被代理的对象,数学计算器类* @return*/public static Object getProxyInstance(Object mathClass) {InvocationHandler invocationHandler = new InvocationHandler() {/*** @param proxy  代理* @param method 代理方法,被调用方法* @param args 代理方法的参数,被调用的参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("动态代理执行前:" + Arrays.toString(args));Object invoke = method.invoke(mathClass, args);System.out.println("动态代理执行后:" + invoke.toString());return invoke;}};// 返回 动态代理类return Proxy.newProxyInstance(mathClass.getClass().getClassLoader(), mathClass.getClass().getInterfaces(), invocationHandler);};

@Test测试类:

package com.ssg.aop;import com.ssg.aop.impl.MathCalculatorImpl;
import com.ssg.aop.interfaces.MathCalculator;
import com.ssg.aop.proxy.dynamic.MathCalculatorDynamicProxy;
import org.junit.jupiter.api.Test;public class DynamicTest {@Testpublic void test() {MathCalculator mathCalculator = new MathCalculatorImpl();MathCalculator dynamicProxy = (MathCalculator) MathCalculatorDynamicProxy.getDynamicProxy(mathCalculator);int add = dynamicProxy.add(1, 2);System.out.println("测试方法执行结果为 = " + add);}
}

结果输出:

动态代理执行前:[1, 2]
方法执行结果 = 3
动态代理执行后:3
测试方法执行结果为 = 3
http://www.dtcms.com/a/349179.html

相关文章:

  • redis集群模式 -批量操作
  • 智慧工业设备巡检误报率↓81%!陌讯多模态融合算法实战优化与边缘部署
  • 【机器学习】6 Frequentist statistics
  • (计算机网络)JWT三部分及 Signature 作用
  • 车企数据资产管理——解读46页大型车企数据资产数据治理体系解决方案【附全文阅读】
  • 计算机系统 C语言运行时对应内存映射 以及 各个段的数据访问下标越界产生的后果
  • Delphi 12 基于 Indy 的 WebServer 的 https 实现的问题
  • HiRAG:用分层知识图解决复杂推理问题
  • ruoyi框架角色分配用户
  • imx6ull-驱动开发篇38——Linux INPUT 子系统
  • leetcode_189 轮转数组
  • 什么嵌入式接入大模型:第二篇基于 STM32 ESP32 的社会服务助手
  • AI重塑跨境电商:选品成功率提升53%+物流效率加快34%,多语种运营成破局关键
  • String的intern方法
  • 数据库服务优化设置
  • nano命令使用方法
  • 备考NCRE三级信息安全技术 --- L1 信息安全保障概述
  • 自编 C# 颜色命名和色彩显示,使用 DataGridView 展示颜色命名、RGB值
  • 推进数据成熟度旅程的 3 个步骤
  • 基于 MATLAB 的信号处理实战:滤波、傅里叶变换与频谱分析
  • 什么是IP代理
  • 智慧农业病虫害监测误报率↓82%!陌讯多模态融合算法实战解析
  • 基于微信小程序校园微店源码
  • 电力电子simulink练习10:反激Flyback电路搭建
  • [leetcode] - 不定长滑动窗口
  • 深度学习卷积神经网络项目实战
  • 电容触控:自电容 vs 互电容
  • Rust 登堂 生命周期(一)
  • 内网后渗透攻击--域控制器安全(1)
  • 控制启动过程