动态代理的两个使用方式(手动实现+SpringAOP实现)-Demo
一、手动实现
1、具体代码
package com.xch.proxy;/*** 具体业务接口** @author XuChenghe* @date 2023/8/18 15:09*/
public interface Star {/*** 唱歌方法** @param name* @return*/String sing(String name);/*** 跳舞方法*/void dance();}
package com.xch.proxy;/*** 具体业务实现类** @author XuChenghe* @date 2023/8/18 15:06*/
public class BigStar implements Star {private String userName;public BigStar(String userName) {this.userName = userName;}/*** {@inheritDoc}*/public String sing(String songName) {System.out.println(this.userName + "正在唱:" + songName);return "谢谢!谢谢!";}/*** {@inheritDoc}*/public void dance() {System.out.println(this.userName + "正在优美的跳舞~~");}}
package com.xch.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 动态代理的工具类(产生代理的)* -手动实现原生动态代理** @author XuChenghe* @date 2023/8/18 15:11*/
public class ProxyUtil {public static Star createProxy(BigStar bigStar) {// 参数1:ClassLoader用于指定一个类加载器// 参数2:指定生成的代理有哪些方法// 参数3:用来指定生成的代理对象要干什么事情(动态代理的核心)Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),new Class[]{Star.class}, new InvocationHandler() {// 回调方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 动态代理要做的事情,会在这里写代码if ("sing".equals(method.getName())) {System.out.println("准备话筒,收钱20万");} else if ("dance".equals(method.getName())) {System.out.println("准备场地,收钱100万");}return method.invoke(bigStar, args);}});return starProxy;}}
package com.xch.proxy;/*** 运行启动测试类** @author XuChenghe* @date 2023/8/18 15:21*/
public class LaunchTest {public static void main(String[] args) {Star starProxy = ProxyUtil.createProxy(new BigStar("杨超越"));String result = starProxy.sing("好日子");System.out.println(result);starProxy.dance();}}
二、SpringAOP实现
1、pom文件依赖
<!-- Spring的AOP切面编程启动环境依赖组 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Spring的事务依赖 -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId>
</dependency>
2、具体代码
package com.xch.proxy_product;/*** 具体业务接口** @author XuChenghe* @date 2023/8/18 15:09*/
public interface Star {/*** 实际生产中使用的代理调用** @param name* @return*/String proxySing(String name);/*** 实际生产中使用的代理调用*/void proxyDance();}
package com.xch.proxy_product;import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;/*** 具体业务实现类** @author XuChenghe* @date 2023/8/18 15:06*/
@Service
public class BigStar implements Star {/*** 唱歌方法** @param songName* @return*/@Transactional(rollbackFor = Exception.class)public String sing(String songName) {System.out.println("杨超越正在唱:" + songName);return "谢谢!谢谢!";}/*** 跳舞方法*/@Transactional(rollbackFor = Exception.class)public void dance() {System.out.println("杨超越正在优美的跳舞~~");}/*** {@inheritDoc}*/@Transactional(rollbackFor = Exception.class)public String proxySing(String songName) {System.out.println("准备话筒,收钱20万");return getCurrentProxy().sing("好日子");}/*** {@inheritDoc}*/@Transactional(rollbackFor = Exception.class)public void proxyDance() {System.out.println("准备场地,收钱100万");getCurrentProxy().dance();}/*** 获取当前类的代理** @return 当前类的代理*/private static BigStar getCurrentProxy() {return (BigStar) AopContext.currentProxy();}}
package com.xch.proxy_product;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;/*** 通用业务的切面类** @author XuChenghe* @date 2023/8/20 8:55*/
@Aspect // 声明该类的作用:切面类
@Component // 等价于@Configuration:交由Spring的IOC容器管理
public class BigStarAspect {/*** 定义公共切入点* -假设proxy_product是service业务层包* -则通过以下表达式匹配该业务包下的所有子孙类的所有public修饰的方法** 另外,配置的切入表达式必须是符合public修饰的方法* 因为,Spring事务即AOP的底层通过动态代理生成代理调用该方法时,* 会判断方法只能是public修饰的Modifier.isPublic(method.getModifiers())*/@Pointcut("execution(public * com.xch.proxy_product..*(..))")public void myPointcut() {// 公共切入点}/*** 配置切面方法(环绕通知):方法增强** @param pjp 连接点:当前切入方法的信息* @return 方法执行的返回结果* @throws Throwable 方法执行时抛出的异常*/@Around("myPointcut()")public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("=====环绕通知(开始)=====");// 前置增强代码Object proceed = pjp.proceed();// 后置/返回增强代码// 最终增强代码// 抛出异常后增强代码System.out.println("=====环绕通知(结束)=====");return proceed;}
}
package com.xch;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** 启用Spring的动态代理,默认使用JDK动态代理(由proxyTargetClass控制)*/
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class SubDynamicProxyApplication {public static void main(String[] args) {SpringApplication.run(SubDynamicProxyApplication.class, args);}}
package com.xch.proxy_product;import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;/*** 运行启动测试类** @author XuChenghe* @date 2023/8/18 15:21*/
@SpringBootTest
public class LaunchTest {@Autowiredprivate Star star;@Testpublic void launch() {String result = star.proxySing("好日子");System.out.println(result);System.out.println();star.proxyDance();// 判断该注入类是否代理类// -Spring的IOC容器中默认都是原生对象// -只有配置了AOP增强的对象才是代理对象System.out.println(AopUtils.isAopProxy(star));}}相关文章:
动态代理的两个使用方式(手动实现+SpringAOP实现)-Demo
一、手动实现 1、具体代码 package com.xch.proxy;/*** 具体业务接口** author XuChenghe* date 2023/8/18 15:09*/ public interface Star {/*** 唱歌方法** param name* return*/String sing(String name);/*** 跳舞方法*/void dance();} package com.xch.proxy;/*** 具体…...
面试话术(MQ+mybatis+nginx+redis+ssm+mysql+linux)
面试话术 RabbitMq1、介绍一下rabbitmq2、如何保证消息确定消息发送成功,并且被消费成功,有什么保障措施3、如何保证消息不被重复消费4、RabbitMQ 宕机了怎么处理 授权话术1、你给我说一下授权认证(登陆注册)的逻辑2、说一下jwt3、…...
JSON的理解
文章目录 1、什么是JSON2、为什么要用JSON3、JSON的格式规定3.1 对象(0bject):对应着JS中的对象3.2 数组(Array):对应着JS中的数组形式3.3 简单形式:对应着JS中的基础数据类型 4、JSON和Js的转换5、JSON对象…...
面试热题(二叉树的最大路径)
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给定一个二叉树的根节点 root…...
C#设计模式之--六大原则 开闭原则
设计模式六大原则是单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则。它们不是要我们刻板的遵守,而是根据实际需要灵活运用。只要对它们的遵守程度在一个合理的范围内,努为做到一个良好的设计。本文主要介绍一下.NET(C#)…...
编写Dockerfile制作自己的镜像并推送到私有仓库
说明:我将用到的私有仓库是Harbor,安装教程参考我的这一篇文章: 安装搭建私有仓库Harbor_Word_Smith_的博客-CSDN博客 一、案例1 1、要求 编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私…...
华为OD-分积木/分苹果
题目描述 哥哥弟弟分一堆积木,每块积木重量不同。弟弟要求平分两组,每组数量可以不同但总重量必须相等。 然而弟弟只会二进制并且加法不进位。例如三块积木 3,5,6 分成两组 [3] 和 [5,6] 弟弟认为 5(二进制1001)加上6(…...
Mysql的引擎有哪些?支持事物么?DB储存引擎有哪些?
Mysql的引擎有哪些?支持事物么?DB储存引擎有哪些? MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用: MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCH…...
【懒加载】js实现懒加载、vue实现图片懒加载指令
懒加载 延迟加载,对于一个很长的页面,优先加载可视区域的内容,其他部分等进入可视区域时再加载 懒加载作用 是一种网页性能优化的方式,它能极大的提升用户体验。比如一个页面中有很多图片,但是首屏只出现几张&#…...
微信小程序教学系列(7)
第七章:小程序安全和权限管理 第一节:小程序安全性保障 在开发小程序时,我们要时刻牢记小程序的安全性。毕竟,我们可不希望我们的小程序被黑客入侵或者用户的隐私被泄露。所以,让我们一起来了解一下如何保障小程序的…...
Android 9.0 kenel和frameworks中修改ram运行内存的功能实现
1.前言 在9.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,在产品后续订单中,在某些机型中需要升级下系统内核配置,项目时间比较仓促,所以 来不及对硬件重新定制,就需要软件方面在ram运行内存的容量大小方面作假,修改ram真实的大小容量,所以就需要在ken…...
PHP实践:获取网络上图片的长宽以及图片类型
🏆作者简介,黑夜开发者,全栈领域新星创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责…...
使用 DPO 微调 Llama 2
简介 基于人类反馈的强化学习 (Reinforcement Learning from Human Feedback,RLHF) 事实上已成为 GPT-4 或 Claude 等 LLM 训练的最后一步,它可以确保语言模型的输出符合人类在闲聊或安全性等方面的期望。然而,它也给 NLP 引入了一些 RL 相关…...
数据库——事务,事务隔离级别
文章目录 什么是事务?事务的特性(ACID)并发事务带来的问题事务隔离级别实际情况演示脏读(读未提交)避免脏读(读已提交)不可重复读可重复读防止幻读(可串行化) 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行。 事务最经典也经常被拿出…...
对《VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeBasic动态库》的改进
《VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeBasic动态库》使用的Activex DLL公共对象是需要先注册的。https://blog.csdn.net/weixin_45707491/article/details/132437502?spm1001.2014.3001.5501 Activex DLL事前注册,一次多用说起来也不是啥大问题&#x…...
【PHP】数据类型运算符位运算
文章目录 数据类型简单(基本)数据类型:4个小类复合数据类型:2个小类特殊数据类型:2个小类类型转换类型判断整数类型浮点类型布尔类型 运算符赋值运算符算术运算符比较运算符逻辑运算符连接运算符错误抑制符三目运算符自…...
使用 Nacos 作为 Spring Boot 配置中心
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
微服务 Eureka
Eureka Eureka是Netflix开源的一个用于构建基于微服务架构的服务发现和注册中心技术。在微服务架构中,系统被拆分成多个小型、自治的服务,每个服务负责特定的业务功能。这些服务需要能够相互发现和通信,这就是Eureka所提供的功能。 Eureka主…...
Spring Boot 事务和事务传播机制
1. 为什么需要事务? 事务定义 将一组操作封装成一个执行单元 (封装到一起),这一组的执行具备原子性, 那么就要么全部成功,要么全部失败. 为什么要用事务? 比如转账分为两个操作: 第一步操作:A 账户-100 元。 第二步操作:B账户 100 元。 如果没有事务&a…...
计算机组成原理(巨巨巨基础篇)
有关《计算机组成原理》课本中有关 内存计算换算(字,位,字节) 个人理解 前面知识点搭建框架,最后两道例题是直观理解体会 主存储器的基本概念 位:存储信息的最小单位,称为存储位或存储元。 背…...
EasyAnimateV5-7b-zh-InP在计算机网络教学视频生成中的应用
EasyAnimateV5-7b-zh-InP在计算机网络教学视频生成中的应用 1. 引言 计算机网络课程的教学一直面临着一个难题:如何将抽象的网络协议、拓扑结构和数据传输过程直观地展示给学生。传统的静态图片和文字描述往往难以让学生真正理解数据包是如何在网络中流动的&#…...
AutoHotkey实战:5分钟搞定Mac/Windows跨平台快捷键统一(附完整脚本)
AutoHotkey实战:5分钟搞定Mac/Windows跨平台快捷键统一(附完整脚本) 对于频繁切换Mac和Windows双系统的开发者来说,最令人抓狂的莫过于两种操作系统下完全不同的快捷键体系。特别是Cmd/Ctrl键位的混乱,常常让人在复制粘…...
破解企业AI应用开发困境:Dify工作流架构的颠覆性价值
破解企业AI应用开发困境:Dify工作流架构的颠覆性价值 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程,自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Dify-W…...
ChromePass终极指南:3分钟找回Chrome浏览器所有保存密码
ChromePass终极指南:3分钟找回Chrome浏览器所有保存密码 【免费下载链接】chromepass Get all passwords stored by Chrome on WINDOWS. 项目地址: https://gitcode.com/gh_mirrors/chr/chromepass 你是否曾在Chrome浏览器中保存了重要账号密码,却…...
开源视觉模型推荐:GLM-4v-9B,高分辨率输入,中文OCR领先
开源视觉模型推荐:GLM-4v-9B,高分辨率输入,中文OCR领先 1. 引言 在当今多模态AI快速发展的时代,视觉-语言模型正成为技术前沿的热点。GLM-4v-9B作为智谱AI最新开源的90亿参数视觉-语言多模态模型,凭借其11201120高分…...
Repomix构建流程解析:TypeScript编译与打包的完整指南
Repomix构建流程解析:TypeScript编译与打包的完整指南 【免费下载链接】repomix 📦 Repomix (formerly Repopack) is a powerful tool that packs your entire repository into a single, AI-friendly file. Perfect for when you need to feed your cod…...
Wan2.1-umt5能力展示:模拟计算机组成原理教学问答
Wan2.1-umt5能力展示:模拟计算机组成原理教学问答 最近在尝试用大模型辅助教学,发现了一个挺有意思的镜像——Wan2.1-umt5。它不像常见的聊天模型,更像是一个专门为理解和生成专业内容设计的“专家”。我突发奇想,让它扮演了一回…...
基于MATLAB的VSG逆变器无源性分析与稳定性研究
基于MATLAB的VSG逆变器无源性分析与稳定性研究 摘要 随着分布式发电和微电网技术的快速发展,逆变器作为新能源并网的关键接口,其稳定性问题日益突出。虚拟同步发电机(VSG)控制技术通过模拟同步发电机的机电特性,为逆变器提供惯性和阻尼支撑,成为提升系统稳定性的重要手…...
MGeo门址地址解析效果展示:高德×达摩院多模态模型真实解析案例集
MGeo门址地址解析效果展示:高德达摩院多模态模型真实解析案例集 1. 引言:当AI开始“读懂”地址 想象一下,你收到一条外卖订单,地址写着“朝阳区望京SOHO T3 B座15楼1501室,到了打电话”。对于骑手来说,这…...
保姆级教程:在YOLOv12中集成CBAM注意力模块(附完整代码与配置文件)
从零实现YOLOv12与CBAM注意力模块的深度整合实战指南 在目标检测领域,YOLO系列算法始终保持着前沿地位。最新发布的YOLOv12在速度和精度之间取得了更好的平衡,而注意力机制的引入则能进一步提升模型对关键特征的捕捉能力。本教程将手把手带你完成CBAM注…...
