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

java动态代理

目录儿

  • 一、代理模式的作用
  • 二、实现代理的方式
  • 三、动态代理的实现
    • 3.1 jdk动态代理
    • 3.2 cglib动态代理

一、代理模式的作用

  • 功能增强: 基于某个功能,再增加一些功能。
    (比如目标类只负责核心功能,其他附属功能通过代理类完成。代理类的方法名与目标类的方法相同,内容不同,在核心功能外加了一些额外逻辑)
  • 控制访问: 防止直接访问目标。

在这里插入图片描述

代理类代理目标类
目标类是实现目标功能的类

二、实现代理的方式

  • 动态代理

    • 特点:
      • 在程序执行过程中,自动使用jdk反射机制创建代理对象(而不需要写.java源文件),并且动态指定要代理的目标类。
    • 优点:
    • 缺点
  • 静态代理

    • 特点:
      • 代理类是自己手动实现的。自己创建一个类作为代理类
      • 要代理的目标类是确定的。
    • 优点:
      • 实现简单,容易理解
      • 在不改变原目标对象代码的情况下,对目标的功能进行拓展
    • 缺点:
      • 当目标类增加了,代理类可能要成倍的增加,代理类过多
      • 当接口的功能增加或修改,会影响所有实现类,修改工作量大,不好管理维护 。

三、动态代理的实现

3.1 jdk动态代理

基于接口实现代理
使用java反射包中的接口和类实现动态代理,要求 代理类和工具类实现同一个接口
其中反射包是java.lang,reflect,里面有三个类:InvocationHandlerMethodProxy
① 创建目标接口

public interface Star{String sing(String name);void dance();
}

② 创建目标类实现目标接口

public class BigStar implements Star {private String name;public BigStar(String name) {this.name = name;}public String sing(String name) {System.out.println(this.name + "正在唱歌儿:" + name);return "谢谢儿!谢谢儿!";}public void dance() {System.out.println(this.name + "正在跳舞儿");}
}

③ 创建对应的处理器实现InvocationHandler接口,重写invoke方法(里面写增强业务)

public class StarInvocationHandler<T> implements java.lang.reflect.InvocationHandler {private final T target; // 存储目标对象public StarInvocationHandler(T target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getName() + "方法执行前增强");Object result = method.invoke(target, args);System.out.println(method.getName() + "方法执行后增强");return result;}
}

④ 创建工厂类,为了简化创建代理对象的过程(这里用了泛型约束,可以不用)

public class ProxyHandlerFactory {/*** 创建 Star 接口的代理对象*/public static <T extends Star> Star createStarProxy(T target) {return (Star) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new StarInvocationHandler<>(target));}}

⑤ 测试调用

public class Main {public static void main(String[] args) {BigStar bigstar = new BigStar("迪丽热巴");Star starProxy = ProxyHandlerFactory.createStarProxy(bigstar);String result = starProxy.sing("老公老公我爱你");System.out.println(result);}
}

结果:
在这里插入图片描述

3.2 cglib动态代理

基于继承实现代理
cglib是一个第三方工具库,能够创建代理对象。
通过继承的方式实现动态代理,通过继承目标类,创建它的子类,在子类中重写父类的同名方法,实现功能的修改。(因为是继承重写的方式实现代理,因此要求目标类不能是final修饰,要重写的方法也不能是final修饰的)。

① 导入cglib依赖
② 创建目标类

public class BigStar {private String name;public BigStar() {}public BigStar(String name) {this.name = name;}public String sing(String name) {System.out.println(this.name + "正在唱歌儿:" + name);return "谢谢儿!谢谢儿!";}public void dance() {System.out.println(this.name + "正在跳舞儿");}
}

③ 创建拦截器

public class BigStarMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(method.getName() + "方法增强前");Object result = methodProxy.invokeSuper(o, objects); // 调用目标类方法System.out.println(method.getName() + "方法增强前");return result;}
}

④ 创建代理对象,测试

public class TestMain {@Testpublic void test() {// 创建与目标对象对应的拦截器BigStarMethodInterceptor bigStarMethodInterceptor = new BigStarMethodInterceptor();// 创建一个增强器对象Enhancer enhancer = new Enhancer();// 设置目标类enhancer.setSuperclass(BigStar.class);// 设置拦截处理器enhancer.setCallback(bigStarMethodInterceptor);// 创建代理对象(根据参数选择对应的 Constructor)BigStar bigStarProxy = (BigStar) enhancer.create(new Class[]{String.class}, new Object[]{"胖迪"});// 调用方法String s = bigStarProxy.sing("猪之歌");System.out.println(s);}
}

运行结果:
在这里插入图片描述

cglib的代理效率高于jdk代理。

如果想看看生成的代理对象长什么养,可以通过设置一个系统属性并指定路径,CgLib会把生成的代理对象写出到该位置:

	// CgLib提供的代理类生成器System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\idea_workspace\\ruoyi\\wipinfo_bigscreen_manager\\admin\\src");

在这里插入图片描述

参考资料:

  1. 哔哩哔哩 黑马程序员磊哥 【黑马磊哥】Java动态代理深入剖析,真正搞懂Java核心设计模式:代理设计模式
    https://www.bilibili.com/video/BV1ue411N7GX?share_source=copy_web
  2. 哔哩哔哩 动力节点 Java-JDK动态代理(AOP)使用及实现原理分析
    https://www.bilibili.com/video/BV1HZ4y1p7F1?share_source=copy_web
  3. 哔哩哔哩 上云_云哥 jdk动态代理,cglib动态代理,代理设计模式,aop切面编程
    https://www.bilibili.com/video/BV1tY411Z799?p=6&share_source=copy_web

相关文章:

java动态代理

目录儿一、代理模式的作用二、实现代理的方式三、动态代理的实现3.1 jdk动态代理3.2 cglib动态代理一、代理模式的作用 功能增强: 基于某个功能&#xff0c;再增加一些功能。 &#xff08;比如目标类只负责核心功能&#xff0c;其他附属功能通过代理类完成。代理类的方法名与目…...

Python 简单可变、复杂可变、简单不可变、复杂不可变类型的copy、deepcopy的行为

copy模块&#xff1a;copy&#xff1a;浅拷贝deepcopy&#xff1a;深拷贝简单可变类型、复杂可变的copy()、deepcopy()&#xff1a;简单不可变、复杂不可变类型的copy()、deepcopy()&#xff1a;结论&#xff1a;对于简单类型的可变类型copy是深拷贝&#xff0c;改变了该拷贝变…...

QML Item

在QML中所有的可视项目都继承自Item&#xff0c;虽然Item本身没有可视化的外观&#xff0c;但它定义了可视化项目的所有属性。 Item可以作为容器使用&#xff1a; Item{Rectangle{id:retc}Rectangle{id:retc1}Rectangle{id:retc2}Rectangle{id:retc3}} item拥有children属性…...

使用xca工具生成自签证书

本文使用 xca 生成自签证书。 概述 之前使用 openssl 生成证书&#xff0c;在 golang 中测试&#xff0c;发现客户端连接失败&#xff0c;经查发现是Subject Alternative Name不支持导致的。因虚拟机 openssl 版本较低&#xff0c;有个功能无法实现&#xff0c;且升级麻烦&…...

Unity IOS 通过命令行导出IPA

新建一个文件然后输入如下内容 #!/usr/bin/env sh /Applications/Unity/Hub/Editor/2020.1.5f1c1/Unity.app/Contents/MacOS/Unity -quit -batchmode -projectPath /Users/zyt/Test -executeMethod Test.BuildEditor.BuildApp cd /Users/zyt/Test/Xcode/unity-xcode xcodebuil…...

「架构」全链路异步模式

总结自尼恩的全链路异步&#xff1a;网关纯异步化网关层的特点&#xff1a;不需要访问业务数据库只做协议转换和流量转发特点是 IO 密集型&#xff0c;特别适合纯异步的架构&#xff0c;可以极大的节省资源。如何进行网关异步化&#xff1f;使用高性能的通信框架Netty&#xff…...

CleanMyMac4.20最新版新增功能及电脑清理垃圾使用教程

CleanMyMac4.20作为知名的Mac清理工具&#xff0c;仅需一键即可快速而安全地清理系统垃圾&#xff0c;释放磁盘空间&#xff0c;因此一直深受Mac用户的喜爱。在不断更新的版本中&#xff0c;CleanMyMac已经不仅仅满足于只做简单的Mac清理工具&#xff0c;而是为Mac用户提供更多…...

Vue2的tsx开发入门完全指南

本篇文章尽量不遗漏重要环节&#xff0c;本着真正分享的心态&#xff0c;不做标题党 下面进入正题&#xff1a; 由于现在vue的官方脚手架已经非常完善我们就不单独配置webpack了&#xff0c;节省大量的时间成本。 首先使用vue/cli创建一个vue模版项目&#xff08;记得是vue/…...

GLSL shader学习系列1-Hello World

这是GLSL shader系列第一篇文章&#xff0c;本文学习目标&#xff1a; 安装编辑工具编写hello world程序 安装插件 我使用VSCode编写shader代码&#xff0c;在VSCode上有两个好用的插件需要先装一下&#xff1a; Shader languages support for VS Code glsl-canvas&#xf…...

Codeforces Round #851 (Div. 2)(A~D)

A. One and Two给出一个数组&#xff0c;该数组仅由1和2组成&#xff0c;问是否有最小的k使得k位置的前缀积和后缀积相等。思路&#xff1a;计算2个数的前缀和即可&#xff0c;遍历判断。AC Code&#xff1a;#include <bits/stdc.h>typedef long long ll; const int N 1…...

内存保护_1:Tricore芯片MPU模块介绍

上一篇 | 返回主目录 | 下一篇 内存保护_1&#xff1a;Tricore芯片MPU模块介绍1 何为MPU2 MPU相关的硬件子系统2.1 基于地址范围保护逻辑说明2.1.1 地址范围寄存器2.1.2 读、写、执行权限寄存器2.1.3 保护集设置位2.1.4 内存保护功能使能位2.1.5 核的内存保护范围获取说明2.1.6…...

Vue3 -- PDF展示、添加签名(带笔锋)、导出

文章目录笔锋签名方案一实现要点实现过程组件引用页面元素添加引用实现代码效果展示缺点方案二修改页面元素替换引用修改代码效果展示完整代码地址实现功能的时候采用了两个方案&#xff0c;主要是第一个方案最后的实现效果并不太理想&#xff0c;但实现起来比较简单&#xff0…...

行测-判断推理-图形推理-样式规律-属性规律-曲直性

左边的图全是由曲线构成的选C1 3 5全是由曲线构成的2 4 6全是由直线构成的第三行的图形有曲有直选A1 3 5有曲有直2 4 6全是直线选D图形有曲有直&#xff0c;排除B D外曲内直->内曲外直->外曲内直->内曲外直->外曲内直->内曲外直所以问号出的图形应该是内曲外直选…...

idea集成Alibaba Cloud Toolkit插件

idea集成Alibaba Cloud Toolkit插件 ​ 使用该插件主要是简化打包、上传、启动服务的相关操作。 ​ 很早之前的方式是使用开发工具&#xff08;eclipse,idea&#xff09;&#xff0c;使用maven命令完成项目打包&#xff08;这里指jar&#xff09;&#xff0c;然后通过shell工…...

Win11 文件夹打开慢或卡顿解决方案

问题 目前是 2023/2/27, 我的 Win11 系统点开一个文件夹要等待 2-3 秒才能加载出来, 使用体验极差。网上查阅大量资料, 有些人在系统更新后这个情况就消失了, 但是我这一直存在, 系统也是当前的最新版, 没有修复。 目前得出的结论是, 因为 Win11 的工具栏占用了过多的资源, 需…...

【PostgreSQL的idle in transaction连接状态】

在平时查询pg_stat_activity这个视图的时候&#xff0c;每一行包含了一个进程的相关信息&#xff0c;包含当前正在执行的SQL&#xff0c;或者会话的状态等等&#xff0c;state字段表示当前进程的状态。在PostgreSQL数据库里&#xff0c;其实代码里总共定义了7种BackendState&am…...

cityengine自定义纹理库资源

背景 cityengine虽然可以将shp生成带纹理的三维模型,但是纹理不一定满足我们的要求,这时候我们就想用我们自己制作的纹理 粗略了解规则文件 了解Building_From_Footprint.cga这个规则文件,具体文件位置默认在 “C:\Users[电脑用户名:如Administrator]\Documents\CityEng…...

taobao.top.secret.bill.detail( 服务商的商家解密账单详情查询 )

&#xffe5;免费必须用户授权 服务商的商家解密账单详情查询&#xff0c;仅对90天内的账单提供SLA保障。 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求示例 TaobaoClient…...

2023软件测试金三银四常见的软件测试面试题-【抓包和网络协议篇】

八、抓包与网络协议 8.1 抓包工具怎么用 我原来的公司对于抓包这块&#xff0c;在App的测试用得比较多。我们会使用fiddler抓取数据检查结果&#xff0c;定位问题&#xff0c;测试安全&#xff0c;制造弱网环境; 如&#xff1a;抓取数据通过查看请求数据&#xff0c;请求行&…...

vue脚手架多页自动化生成实践

前言 在前端开发过程中&#xff0c;常常面对多种业务场景。到目前为止&#xff0c;前端对于不同场景的处理通常会采用不同的渲染方案来组合处理&#xff0c;常见的渲染方案包括&#xff1a;CSR(Client Side Rendering)、SSR(Server Side Rendering)、SSG(Static Site Generati…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...