Spring AOP在业务中常见的使用方式

目录

1、动态代理

1.1、jdk动态代理

1.2、cglib动态代理

1.3、动态代理的好处

2、什么是AOP

2.1、AOP常用术语

2.2、切面的构成

3、使用aspectJ框架实现AOP

3.1、aspectJ简介

声明实现类ServiceImpl

声明切面

3.3、@AfterReturning后置通知

切面类代码

3.4、@Around环绕通知(功能最强的通知)


1、动态代理

1.1、jdk动态代理

使用jdk中的Proxy,Method,InvocaitonHanderl创建代理对象。 jdk动态代理要求目标类必须实现接口,关于细节本文就不赘述了。
要求:

必须要有接口
目标类必须实现接口(一个或多个)

1.2、cglib动态代理

第三方的工具库,创建代理对象,原理是继承。 通过继承目标类,创建子类。子类就是代理对象。 要求目标类不能是final的,方法也不能是final的

1.3、动态代理的好处

在目标类源代码不改变的情况下,增加功能。
减少代码的重复
专注业务逻辑代码
解耦合,让你的业务功能和日志,事务非业务功能分离。

2、什么是AOP

面向切面编程, 基于动态代理的,可以使用jdk,cglib两种代理方式。Aop就是动态代理的规范化, 把动态代理的实现步骤,方式都定义好了, 让开发人员用一种统一的方式,使用动态代理实现。

2.1、AOP常用术语

Aspect: 切面,给你的目标类增加的功能,就是切面。 像日志,事务都是切面。切面的特点: 一般都是非业务方法,独立使用的。
JoinPoint:连接点 ,连接业务方法和切面的位置。需要给哪个方法增加切面,这个方法就是连接点。
Pointcut : 切入点 ,指多个连接点方法的集合。
目标对象: 给哪个类的方法增加功能, 这个类就是目标对象。
Advice:通知,通知表示切面功能执行的时间。

2.2、切面的构成

切面就是要给别的方法进行增强的方法,一个切面有以下三个要素。

切面的功能代码,切面干什么
切面的执行位置,使用Pointcut表示切面执行的位置
切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后。

3、使用aspectJ框架实现AOP

3.1、aspectJ简介

aspectJ是一个开源的专门做aop的框架。spring框架中集成了aspectj框架,通过spring就能使用aspectj的功能。aspectJ框架实现aop有两种方式:

使用xml的配置文件 : 配置全局事务
使用注解,我们在项目中要做aop功能,一般都使用注解, aspectj有5个注解。
再使用aspectJ做aop之前要先加入aspectJ依赖。

    <!--aspectJ依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.5.RELEASE</version></dependency>

3.2 @Before前置通知
前置通知注解修饰的切面在连接点方法之前执行。下面通过一段代码体验一下。

声明接口IService

public interface IService {void doSome(String name, int age);
}

声明实现类ServiceImpl

public class ServiceImpl implements IService {@Overridepublic void doSome(String name, int age) {System.out.println("===doSome()===");}
}

声明切面

@Aspect
public class MyAspectJ {/*** 定义功能增强方法(方法就是切面)* 1、方法的必须为public* 2、方法无返回值* 3、方法名称自定义* 4、方法可以有参数,也可以没有参数* 5、方法的定义上方加入注解,表示切入点的执行时机@Before(value = "execution(public void com.mms.ba01.ServiceImpl.doSome(String,int))")public void beforeLog() {System.out.println("前置通知->系统当前时间:" + new Date());}*//*前置通知,带方法参数的切面切面方法有参数时要求参数是JoinPoint类型,参数名自定义,该参数就代表了连接点方法,即doSome方法使用该参数可以获取切入点表达式、切入点方法签名、目标对象等*/@Before(value = "execution(* *..ServiceImpl.doSome(..))")public void beforeLog(JoinPoint jp) {System.out.println("连接点方法的方法签名="+jp.getSignature());System.out.println("连接点方法的方法名="+jp.getSignature().getName());//获取连接点方法参数Object[] args = jp.getArgs();for (Object arg : args) {System.out.println("arg="+arg);}}
}

测试

public class MyTest {//aop前置通知@Testpublic void test01() {String config = "ba01/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(config);//获取目标对象,此时的service就是spring生成的代理对象//注意返回值类型是接口类型,不能是实现类接口,否则报错IService service = (IService) ac.getBean("service");//使用代理对象执行方法service.doSome("张三",23);}
}

3.3、@AfterReturning后置通知

在IService接口中新增方法:

Student doStudent(Student student);

在ServiceImpl实现doStudent方

    @Overridepublic Student doStudent(Student student) {return student;}

切面类代码

@Aspect
public class MyAspectJ {/*** @AfterReturning: 后置通知,在连接点方法执行之后执行后置通知方法* 方法定义格式:* 1、公共方法* 2、没有返回值* 3、方法名称自定义* 4、与前置通知一样,可以有JoinPoint类型参数,该参数表示连接点方法对象;还可以有一个*    Object类型参数,用于接收连接点方法的执行结果,注意该参数的参数名必须与切入点表达式*    的returning属性的属性值一致,表示将returning属性值赋给Object对象*//*@AfterReturning(value = "execution(* *..ServiceImpl.doOther(..))", returning = "obj")public void afterTransaction(JoinPoint jp, Object obj) {System.out.println("doOther方法的返回参数="+obj);System.out.println("事务已提交...");经过验证:在后置通知切面内不能改变连接点方法的返回值}*/@AfterReturning(value = "execution(* *..ServiceImpl.doStudent(..))", returning = "obj")public void afterTransaction(JoinPoint jp, Object obj) {System.out.println(obj);Student student = new Student();student.setName("李四");student.setAge(24);obj = student;System.out.println("===查看是否改变了连接点方法的返回值==="+obj);/*经过验证:在后置通知切面内不能改变连接点方法的返回值*/}
}

3.4、@Around环绕通知(功能最强的通知)

环绕通知是功能最强的通知,它的本质就是jdk动态代理,他可以在连接点方法之前和之后都可以执行,最厉害的是他可以改变连接点方法的执行结果(返回结果)。还是拿上面的doStudent(Student student)方法来说明,经过验证前置通知和后置通知都不能改变doStudent(Student student)方法的返回值。下面看一下环绕通知是如何做的。

切面类

@Aspect
public class MyAspectJ {/*环绕通知:@Around(切入点表达式)1、环绕通知是最重要的一个通知,他表示在连接点方法的前或者后都可以执行,它的本质就是jdk动态代理的invoke方法的method参数2、定义格式a、publicb、必须有返回值,类型为Object*/@Around(value = "pointCut()")/*再次回忆一下jdk动态代理的invoke方法的定义@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {是不是感觉与下面的方法定义眼熟啊,没错,环绕通知切面的定义实质上就是jdk动态代理*/public Object around(ProceedingJoinPoint pj) throws Throwable {System.out.println("环绕通知在连接点方法之前执行了...");Object result = null;result = pj.proceed();Student student = new Student();student.setName("李四");student.setAge(24);//改变连接点方法返回值result = student;System.out.println("事务已提交...");return result;}/*使用pointcut管理切面表达式1、在一个切面类中,若多个切面的切面表达式均为同一个,每次都要写重复的代码,此时就可以使用pointcut来管理切面表达式了2、定义格式:公共public无返回值无参数*/@Pointcut(value = "execution(* *.doStudent(..))")public void pointCut() {//空方法体}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/719691.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2核4G云服务器租用价格_2核4G云主机优惠价格_2024年报价

租用2核4G服务器费用价格&#xff0c;2核4G云服务器多少钱一年&#xff1f;1个月费用多少&#xff1f;阿里云2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年&#xff1b;腾讯云轻量2核4G服务器5M带宽165元一年、252元15个月、540元三…

Spring IOC在业务中常见的使用方式

目录 1、什么是IOC 2、java实现创建对象的方式有哪些 3、基于配置文件的di实现 3.1、什么是di 3.2、入门案例 3.3、环境搭建 接口和实现类 ioc配置文件 测试程序 3.4、案例总结 3.5、简单类型属性的赋值&#xff08;set注入&#xff09; set注入要求 JavaBean sp…

前端项⽬⽂件很⼤,⽽且⻚⾯访问速度慢,如何在前端侧提⾼性能?

1. 网络优化 减少HTTP请求的数量&#xff0c;可以通过合并CSS和JavaScript文件来实现。使用CDN&#xff08;内容分发网络&#xff09;来加速静态资源的加载速度。对图片进行压缩&#xff0c;选择正确的格式&#xff0c;并实现懒加载技术&#xff0c;以减少页面初次加载时的数据…

代码随想录day12(2)字符串:重复的子字符串(leetcode459)

题目要求&#xff1a;给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 思路&#xff1a; 一、首先对于暴力解法&#xff0c;可以枚举所有的字串进行判断。但是枚举时实际上只需…

rt thread stdio如何同时生成bin和hex

一、rt thread stdio默认生成bin文件&#xff1a; rt thread stdio 软件编译时&#xff0c;默认生成bin文件&#xff1b; 二、rt thread stdio如何同时生成bin和hex 右键单击-->项目-->属性-->C/C构建-->设置-->构建步骤-->(构建后步骤)命令&#xff1a; …

视频如何无水印保存?这三种下载方法赶紧收藏

在互联网时代&#xff0c;视频已成为我们获取信息、娱乐休闲的重要途径。然而&#xff0c;有时我们想要保存或分享某些视频时&#xff0c;却发现下载起来却带有水印。为了解决这个问题&#xff0c;今天给大家带来几个无水印下载的方法。 方法一&#xff1a;水印云 水印云是一…

Python使用模块和库编程

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 路在脚下&#xff0c;勇往直前&#x…

Spring Boot2.2.4版本启动项目时,访问登录接口显示页面不存在

问题触发场景&#xff1a;IDEA 2023.3.4 SpringBoot 2.2.4 上面4张图片分别是项目结构、Spring Boot启动配置、SpringMVC配置和页面展示在项目中存放的位置&#xff0c;表面上看上去没有太大问题&#xff0c;项目应该会达到预期结果&#xff0c;但是bug总是在不经意间出现&…

MySQL数据库运维第一篇(日志与主从复制)

文章目录 一、错误日志二、二进制日志三、查询日志四、慢查询日志&#xff08;记录超时的sql语句&#xff09;五、主从复制概括六、主从复制原理七、搭建主从复制八、主从复制的测试 在这篇深入的技术文章中&#xff0c;作者将以明晰透彻的方式详细介绍MySQL数据库中关键的日志…

XGB-16:自定义目标和评估指标

概述 XGBoost被设计为一个可扩展的库。通过提供自定义的训练目标函数和相应的性能监控指标&#xff0c;可以扩展它。本文介绍了如何为XGBoost实现自定义的逐元评估指标和目标。 注意&#xff1a; 排序不能自定义 在接下来的两个部分中&#xff0c;将逐步介绍如何实现平方对数…

【EAI 027】Learning Interactive Real-World Simulators

Paper Card 论文标题&#xff1a;Learning Interactive Real-World Simulators 论文作者&#xff1a;Mengjiao Yang, Yilun Du, Kamyar Ghasemipour, Jonathan Tompson, Leslie Kaelbling, Dale Schuurmans, Pieter Abbeel 作者单位&#xff1a;UC Berkeley, Google DeepMind, …

【 Docker 容器详细介绍和说明】

Docker 容器详细介绍和说明 Docker 容器详细介绍和说明Docker 安装步骤&#xff08;以Ubuntu为例&#xff09;&#xff1a;使用Docker创建并运行容器&#xff1a;VSCode远程连接Docker容器&#xff1a;步骤1&#xff1a;配置Docker环境步骤2&#xff1a;配置PyCharm步骤3&#…

日本发动全面侵华战争他们在怕什么?为何不敢动陕西,

日本全面侵华战争之谜&#xff1a;恐惧与野心的交织 在二十世纪三十年代&#xff0c;日本帝国主义以令人发指的暴行和残忍手段&#xff0c;对中国发动了全面侵华战争。然而&#xff0c;在这场战争中&#xff0c;有一个引人关注的现象&#xff1a;日本侵略者在进攻过程中&#…

python和nodejs一键安装当前项目所有依赖

python和nodejs一键安装当前项目所有依赖。群里有人问怎么快速安装网上下载的源码里面的依赖。所以在这里分享一下。更多问题可以自己加群917400262问我。 目录导航 1.0 python一键安装当前项目所有依赖2.0 nodejs一键安装当前项目所有依赖 1.0 python一键安装当前项目所有依赖…

snakemake: 基础知识

为了有效地学习和使用 Snakemake&#xff0c;你需要具备一定的基础知识。这些基础知识将帮助你更好地理解 Snakemake 的工作原理和如何在你的项目中应用它。以下是学习 Snakemake 所需的一些基础知识&#xff1a; 1. Python 编程 Snakemake 是用 Python 编写的&#xff0c;并…

聊聊国内「类Sora模型」发展现状,和 Sora 的差距到底有多大?

2024 年 2 月 16 日。 就在谷歌发布他新一代的多模态大模型 Gemini 1.5 Pro 的同一天&#xff0c;OpenAI 带着新一代的文生视频模型 Sora 再次抓住了全世界人们的眼球。 “颠覆”、“炸裂”、“变天”、“疯狂”&#xff0c;类似的形容词一夜之间簇拥在 Sora 周围&#xff0c;…

网络传输基本流程(封装,解包)+图解(同层直接通信的证明),报头分离问题,协议定位问题,协议多路复用

目录 网络传输基本流程 引入 封装 过程梳理 图解 报文 解包 过程梳理 图解 -- 同层直接通信的证明 总结 解包时的报头分离问题 举例 -- 倒水 介绍 自底向上传输时的协议定位问题 介绍 解决方法 协议多路复用 介绍 优势 网络传输基本流程 引入 首先,我们明确…

VS查看C++头文件(.h文件)的函数列表

这里使用的是VS2019举例 如下图查看Actor.h文件中的函数列表 设置步骤如下图

【d35】【Java】【力扣】28. 找出字符串中第一个匹配项的下标

题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入&#xff1a;haystac…

【大数据】通过 docker-compose 快速部署 MinIO 保姆级教程

文章目录 一、概述二、MinIO 与 Ceph 对比1&#xff09;架构设计对比2&#xff09;数据一致性对比3&#xff09;部署和管理对比4&#xff09;生态系统和兼容性对比 三、前期准备1&#xff09;部署 docker2&#xff09;部署 docker-compose 四、创建网络五、MinIO 编排部署1&…