动态代理代码示例
理解动态代理
- 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的,而不是在编译时就已经确定的
- 性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强
- 为什么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();}
相关文章:
动态代理代码示例
理解动态代理 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的,而不是在编译时就已经确定的性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强为什么JDK动态代理只能代理有接口的类? 因为Proxy.newProxyIns…...
SpringBoot+Activiti7工作流使用进阶实例-高亮显示BPMN流程图( SpringBoot+Activiti+mybatis+shiro实现)
文章目录 说明绘制流程图排他网关设置任务节点设置创建工程修改 pom.xml 文件准备数据库的表和测试数据修改 application.yml 文件配置静态资源Shiro 相关配置ShiroConfiguration.javaMyShiroRealm.java流程控制器添加静态的资源和模板页面运行结果截图源码地址说明 使用 Spri…...
C#使用Lazy<T>提高性能
以下是一些适合使用Lazy<T>的场景: 单例模式 在实现单例模式时,Lazy<T>是非常有用的。如前面提到的示例,它可以确保单例对象在首次被访问时才进行创建,同时在多线程环境下也能保证正确的行为。这种方式比传统的双重检…...
创建读取比特币1P类型地址
创建读取比特币1P类型地址 比特币的地址类型有多种,其中 P2TR(Pay-to-Taproot)地址是基于最近的升级(Taproot)引入的一个新类型。本文将介绍如何创建和读取比特币的 1P 类型地址,主要通过 JavaScript 和相…...
从零开始Hadoop集群环境搭建
目录 1. Centos7.5硬件配置1.1 创建虚拟机1.2 虚拟机系统设置 2. IP地址和主机名称配置3. 软件配置3.1 安装 epel-release3.2 卸载虚拟机自带的JDK3.3 克隆虚拟机3.4 修改克隆虚拟机的IP3.5 JDK安装3.6 Hadoop安装 4. Hadoop目录结构 1. Centos7.5硬件配置 1.1 创建虚拟机 1.2…...
Copley耐环境伺服驱动器 极端环境下高精度控制解决方案
全球工业环境的日益复杂多变,对伺服驱动器的要求不再局限于基本的性能参数,而是在极端环境下的稳定性与可靠性。Copley耐环境伺服驱动器以卓越的性能和出色的环境适应性,为工业自动化领域的高精度控制提供了可靠的解决方案。 一、多样化的产…...
前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析
本文属于进阶篇,并不是太适合新人阅读,但纯粹的学习还是可以的,因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端,提前预习和复习下。ddp协议是一个C/S架构的协议,但是客户端也同时可以是服务端。 什…...
基于Zynq SDIO WiFi移植一(支持2.4/5G)
基于SDIO接口的WIFI,在应用上,功耗低于USB接口,且无须USB Device支持,满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…...
数据结构与算法篇(刷题篇 - 链表)
目录 1. 反转链表(简单) 1.1. 题目描述 1.2. 解题思路 方法一:迭代(推荐使用) 方法二:递归(扩展思路) 方法三:使用栈解决 方法四:双链表求解 2. 链表内…...
TinyAgent: 从零开始构建最小化Agent系统
引言 随着大模型(LLM)的崛起,特别是ChatGPT等大模型的广泛应用,基于LLM的系统越来越受欢迎。然而,尽管大模型具备强大的生成能力和推理能力,它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...
Android Studio New里面没有New Flutter Project
跟着Flutter中文网的配置教程,安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次,依然没有效果。 原来是没有把Android APK Suppor…...
linux信号 | 学习信号四步走 | 透析信号是如何被处理的?
前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章…...
mysql语句执行过程
具体流程如下: 1】当客户端的SOL发送到MySQL时,首先是到达服务器层的连接器,连接器会对你此次发起的连接进行权限校验,以此来获取你这个账号拥有的权限。当你的账号或密码不正确时,会报用户错误。连接成功如果后续没有任何操作&am…...
最新版本SkyWalking【10.1.0】部署
这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…...
WSL2 中配置桥接模式、虚拟交换机及固定 IP
WSL2 中配置桥接模式、虚拟交换机及固定 IP 一、创建虚拟交换机1.1 使用 Hyper-V 管理器创建虚拟交换机1.2 使用 PowerShell 创建虚拟交换机 二、更新 WSL 配置三、设置 WSL2 中的静态 IP、网关和 DNS3.1 编辑网络配置文件3.2 应用网络配置3.3 测试网络连接 四、重启 WSL 在使用…...
Unite Shanghai 2024 团结引擎专场 | 团结引擎 OpenHarmony 工程剖析
在 2024 年 7 月 24 日的 Unite Shanghai 2024 团结引擎专场演讲中,Unity中国 OpenHarmony 技术负责人刘伟贤对团结引擎导出的 OpenHarmony 工程进行了细节剖析,详细讲解 XComponent 如何与引擎结合,UI 线程和引擎线程的关联以及 ts/ets 的代…...
计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python毕业设计 Python毕业设计选题 Spark 大数据【附源码+安装调试】
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
2022CCPC绵阳站VP题解报告(CGHMAE六题)
文章目录 2022CCPC绵阳站VP题解报告前言[Problem - C ](https://codeforces.com/gym/104065/problem/C) (签到思维)[H (codeforces.com)](https://codeforces.com/gym/104065/problem/H) (签到构造)[Problem - G ](https://codefo…...
代码随想录day23:贪心part1
455. 分发饼干 class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int res 0;int index s.length - 1;for(int i g.length - 1; i > 0; i--){if(index > 0 && s[index] > g[i]){res;index--;}}return r…...
通过网页设置参数,submit还是json
在通过网页设置参数并发送到服务器时,选择使用submit(通常是通过HTML表单的提交)还是直接发送JSON数据(通常是通过AJAX请求,如使用fetch API)取决于几个因素,包括你的服务器端如何处理这些请求、…...
ChipDNA PUF技术:从晶体管失配到硬件安全密钥的工程实践
1. 项目概述:当芯片拥有“DNA”,嵌入式安全进入新纪元在嵌入式系统设计领域,安全从来不是一个可以事后弥补的附加功能,而是必须从硬件层面开始构建的基石。随着物联网设备的爆炸式增长,从智能门锁到工业控制器…...
Go语言性能优化最佳实践
Go语言性能优化最佳实践 1. 优化清单 使用Benchmark定位热点减少内存分配使用goroutine池选择合适的数据结构优化数据库查询使用缓存 2. 总结 性能优化需要结合实际情况,避免过度优化。...
Taotoken API密钥管理与访问控制功能初体验
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken API密钥管理与访问控制功能初体验 1. 引言 在将大模型能力集成到实际应用或团队协作流程中时,API密钥的管理…...
(最新版)GitGitHub实操图文详解教程(10)—SSH
版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 1. 应用场景 前面几课已经完成了本地Git基础操作:先通过git init初始化仓库,再用git status查看状态,用git add把修改加入暂存区,用git commit创建本地提交,最后用git log查看提交历史。到…...
MTK手机用上高通QC快充,背后多出的那颗‘xmusb350’芯片到底在忙啥?
MTK手机为何需要外挂xmusb350芯片实现高通QC快充? 当你在电商平台搜索"支持QC快充的MTK手机"时,可能会发现一个有趣的现象:采用联发科处理器的机型在充电模块描述中,常会特别标注"搭载独立QC协议芯片"。这背后…...
基于遗传算法的VRPTW问题求解:从元胞数组编码到多约束优化
1. 遗传算法与VRPTW问题初探 第一次接触带时间窗的车辆路径问题(VRPTW)时,我被它复杂的约束条件弄得头晕眼花。想象一下你是一家物流公司的调度员,手上有7辆载重不同的货车,需要给16个客户送货。每个客户都有特定的需求…...
工具推荐:HTML5+AI开发必备的前端调试工具
工具推荐:HTML5AI开发必备的前端调试工具 工具推荐:HTML5AI开发必备的前端调试工具📝 本章学习目标:本章聚焦职业发展,帮助读者规划HTML5AI的学习与职业路径。通过本章学习,你将全面掌握"工具推荐&…...
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验 在嵌入式开发中,ADC(模数转换器)是连接模拟世界与数字世界的关键桥梁。无论是电池电压监测、环境光传感还是工业控制中的各种模拟量采集,AD…...
告别‘有线无网’:手把手修复Ubuntu 20.04上RTL8168网卡的驱动‘掉链子’问题
深度排查Ubuntu 20.04下RTL8168网卡驱动的疑难杂症 当你满怀期待地在工作站上安装好Ubuntu 20.04,准备开始一天的高效开发时,却发现网络连接图标上那个刺眼的红色叉号——有线网络无法连接。这种"有线无网"的窘境,对于依赖网络工作…...
网络工程师避坑指南:eNSP中配置Eth-Trunk链路聚合的5个常见错误与排查方法
网络工程师避坑指南:eNSP中配置Eth-Trunk链路聚合的5个常见错误与排查方法 在华为eNSP模拟器中配置Eth-Trunk链路聚合时,许多网络工程师都会遇到各种"翻车"现场。明明按照教程一步步操作,却发现带宽没有叠加、端口状态异常…...
