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

动态代理的两个使用方式(手动实现+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、如何保证消息确定消息发送成功&#xff0c;并且被消费成功&#xff0c;有什么保障措施3、如何保证消息不被重复消费4、RabbitMQ 宕机了怎么处理 授权话术1、你给我说一下授权认证&#xff08;登陆注册&#xff09;的逻辑2、说一下jwt3、…...

JSON的理解

文章目录 1、什么是JSON2、为什么要用JSON3、JSON的格式规定3.1 对象&#xff08;0bject)&#xff1a;对应着JS中的对象3.2 数组&#xff08;Array&#xff09;&#xff1a;对应着JS中的数组形式3.3 简单形式&#xff1a;对应着JS中的基础数据类型 4、JSON和Js的转换5、JSON对象…...

面试热题(二叉树的最大路径)

路径 被定义为一条从树中任意节点出发&#xff0c;沿父节点-子节点连接&#xff0c;达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给定一个二叉树的根节点 root…...

C#设计模式之--六大原则 开闭原则

设计模式六大原则是单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则。它们不是要我们刻板的遵守&#xff0c;而是根据实际需要灵活运用。只要对它们的遵守程度在一个合理的范围内&#xff0c;努为做到一个良好的设计。本文主要介绍一下.NET(C#)…...

编写Dockerfile制作自己的镜像并推送到私有仓库

说明&#xff1a;我将用到的私有仓库是Harbor&#xff0c;安装教程参考我的这一篇文章&#xff1a; 安装搭建私有仓库Harbor_Word_Smith_的博客-CSDN博客 一、案例1 1、要求 编写Dockerfile制作Web应用系统nginx镜像&#xff0c;生成镜像nginx:v1.1&#xff0c;并推送其到私…...

华为OD-分积木/分苹果

题目描述 哥哥弟弟分一堆积木&#xff0c;每块积木重量不同。弟弟要求平分两组&#xff0c;每组数量可以不同但总重量必须相等。 然而弟弟只会二进制并且加法不进位。例如三块积木 3,5,6 分成两组 [3] 和 [5,6] 弟弟认为 5&#xff08;二进制1001&#xff09;加上6&#xff08…...

Mysql的引擎有哪些?支持事物么?DB储存引擎有哪些?

Mysql的引擎有哪些&#xff1f;支持事物么&#xff1f;DB储存引擎有哪些&#xff1f; MySQL有多种存储引擎&#xff0c;每种存储引擎有各自的优缺点&#xff0c;可以择优选择使用&#xff1a; MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCH…...

【懒加载】js实现懒加载、vue实现图片懒加载指令

懒加载 延迟加载&#xff0c;对于一个很长的页面&#xff0c;优先加载可视区域的内容&#xff0c;其他部分等进入可视区域时再加载 懒加载作用 是一种网页性能优化的方式&#xff0c;它能极大的提升用户体验。比如一个页面中有很多图片&#xff0c;但是首屏只出现几张&#…...

微信小程序教学系列(7)

第七章&#xff1a;小程序安全和权限管理 第一节&#xff1a;小程序安全性保障 在开发小程序时&#xff0c;我们要时刻牢记小程序的安全性。毕竟&#xff0c;我们可不希望我们的小程序被黑客入侵或者用户的隐私被泄露。所以&#xff0c;让我们一起来了解一下如何保障小程序的…...

Android 9.0 kenel和frameworks中修改ram运行内存的功能实现

1.前言 在9.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,在产品后续订单中,在某些机型中需要升级下系统内核配置,项目时间比较仓促,所以 来不及对硬件重新定制,就需要软件方面在ram运行内存的容量大小方面作假,修改ram真实的大小容量,所以就需要在ken…...

PHP实践:获取网络上图片的长宽以及图片类型

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…...

使用 DPO 微调 Llama 2

简介 基于人类反馈的强化学习 (Reinforcement Learning from Human Feedback&#xff0c;RLHF) 事实上已成为 GPT-4 或 Claude 等 LLM 训练的最后一步&#xff0c;它可以确保语言模型的输出符合人类在闲聊或安全性等方面的期望。然而&#xff0c;它也给 NLP 引入了一些 RL 相关…...

数据库——事务,事务隔离级别

文章目录 什么是事务?事务的特性(ACID)并发事务带来的问题事务隔离级别实际情况演示脏读(读未提交)避免脏读(读已提交)不可重复读可重复读防止幻读(可串行化) 什么是事务? 事务是逻辑上的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行。 事务最经典也经常被拿出…...

对《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事前注册&#xff0c;一次多用说起来也不是啥大问题&#x…...

【PHP】数据类型运算符位运算

文章目录 数据类型简单&#xff08;基本&#xff09;数据类型&#xff1a;4个小类复合数据类型&#xff1a;2个小类特殊数据类型&#xff1a;2个小类类型转换类型判断整数类型浮点类型布尔类型 运算符赋值运算符算术运算符比较运算符逻辑运算符连接运算符错误抑制符三目运算符自…...

使用 Nacos 作为 Spring Boot 配置中心

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

微服务 Eureka

Eureka Eureka是Netflix开源的一个用于构建基于微服务架构的服务发现和注册中心技术。在微服务架构中&#xff0c;系统被拆分成多个小型、自治的服务&#xff0c;每个服务负责特定的业务功能。这些服务需要能够相互发现和通信&#xff0c;这就是Eureka所提供的功能。 Eureka主…...

Spring Boot 事务和事务传播机制

1. 为什么需要事务? 事务定义 将一组操作封装成一个执行单元 (封装到一起)&#xff0c;这一组的执行具备原子性, 那么就要么全部成功&#xff0c;要么全部失败. 为什么要用事务? 比如转账分为两个操作: 第一步操作:A 账户-100 元。 第二步操作:B账户 100 元。 如果没有事务&a…...

计算机组成原理(巨巨巨基础篇)

有关《计算机组成原理》课本中有关 内存计算换算&#xff08;字&#xff0c;位&#xff0c;字节&#xff09; 个人理解 前面知识点搭建框架&#xff0c;最后两道例题是直观理解体会 主存储器的基本概念 位&#xff1a;存储信息的最小单位&#xff0c;称为存储位或存储元。 背…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

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

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

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...