动态代理的两个使用方式(手动实现+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…...
计算机组成原理(巨巨巨基础篇)
有关《计算机组成原理》课本中有关 内存计算换算(字,位,字节) 个人理解 前面知识点搭建框架,最后两道例题是直观理解体会 主存储器的基本概念 位:存储信息的最小单位,称为存储位或存储元。 背…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
