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

Spring-aop特点,专业术语及案例演示

一.aop简介

AOP(Aspect-Oriented Programming)是Spring框架的一个重要特性,它通过将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来,以模块化的方式在整个应用程序中重复使用。以下是关于AOP的简介及其特点:

简介:

  • AOP是一种编程范式,它通过将横切关注点切割出来,将其模块化,并将其应用于多个类和模块,以提高代码的重用性和可维护性。
  • 横切关注点是指与核心业务逻辑无关但存在于多个类或模块中的非功能性需求,例如日志记录、性能监控、事务管理等。

特点:

  1. 模块化:AOP允许将横切关注点从核心业务逻辑中提取出来,形成独立的切面(Aspect),使得关注点的逻辑可以独立于各个模块。
  2. 解耦:AOP通过解耦横切关注点与核心业务逻辑,使得它们可以独立演化和变化,提高了模块之间的松耦合程度。
  3. 重用性:AOP允许将切面应用于多个类和模块,从而实现了关注点的重用,避免了代码的重复编写。
  4. 可维护性:将横切关注点抽象为切面后,使得代码结构更清晰,易于理解和维护。
  5. 动态性:AOP可以在运行时动态地将切面应用到目标对象上,而不需要修改目标对象的源代码,增强了系统的灵活性和可扩展性。
  6. 多样性:Spring框架支持不同类型的切面编程,包括基于代理的AOP和基于字节码增强的AOP。这样可以选择最适合应用程序需求的AOP实现方式。

在Spring框架中,AOP的实现采用了代理模式和动态代理技术。Spring提供了多种AOP的实现方式,包括基于XML配置的AOP、基于注解的AOP和基于纯Java配置的AOP(JavaConfig)等,开发者可以根据具体需求选择适合的方式来配置和使用AOP。

 二.aop中的专业术语

  1. 切面(Aspect):切面是一个模块化单元,用于解耦和封装横切关注点的逻辑。切面由切点和通知组成,它定义了何时在何处应用通知。

  2. 切点(Pointcut):切点定义了在应用程序中哪些位置应该应用通知。它通过表达式或模式匹配规则来指定需要被拦截的连接点(Join Point)。

  3. 连接点(Join Point):连接点是在应用程序执行过程中可以插入切面的特定点。例如方法执行、异常抛出、字段访问等都可以是连接点。

  4. 通知(Advice):通知是在切面的特定连接点上执行的动作。在Spring AOP中,有以下几种通知类型:

    • 前置通知(Before Advice):在连接点之前执行的通知。
    • 后置通知(After Advice):在连接点之后执行的通知。
    • 返回通知(After Returning Advice):在连接点成功完成后执行的通知。
    • 异常通知(After Throwing Advice):在连接点发生异常时执行的通知。
    • 环绕通知(Around Advice):在连接点前后都执行的通知,可以控制方法的执行。
  5. 引入(Introduction):引入是一种给现有类添加新方法或属性的方式。它允许在不修改原始类代码的情况下,向类添加新功能。

  6. 织入(Weaving):织入是将切面应用到目标对象上以创建新的代理对象的过程。在Spring AOP中,织入可以在编译时、类加载时或运行时进行。

  7. 目标对象(Target Object):目标对象是被切面通知的真实对象。它是应用程序中具体业务逻辑的实现。

  8. 异常处理(Exception Handling):异常处理是在连接点发生异常时,切面执行的特定动作。它可以捕获和处理异常,提供错误处理或回滚事务等功能。

三.案例演示 

1.前置通知

1.1 先准备接口

package com.YU.aop.biz;public interface IBookBiz {// 购书public boolean buy(String userName, String bookName, Double price);// 发表书评public void comment(String userName, String comments);
}

1.2然后再准备好实现类

package com.YU.aop.biz.impl;import com.YU.aop.biz.IBookBiz;
import com.YU.aop.exception.PriceException;public class BookBizImpl implements IBookBiz {public BookBizImpl() {super();}public boolean buy(String userName, String bookName, Double price) {// 通过控制台的输出方式模拟购书if (null == price || price <= 0) {throw new PriceException("book price exception");}System.out.println(userName + " buy " + bookName + ", spend " + price);return true;}public void comment(String userName, String comments) {// 通过控制台的输出方式模拟发表书评System.out.println(userName + " say:" + comments);}}

1.3对我们的目标对象进行JavaBean配置 

<!--目标对象--><bean class="com.YU.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

1.4 编写前置系统日志通知

package com.YU.aop.advice;import java.lang.reflect.Method;
import java.util.Arrays;import org.springframework.aop.MethodBeforeAdvice;/*** 买书、评论前加系统日志* @author YU**/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//		在这里,可以获取到目标类的全路径及方法及方法参数,然后就可以将他们写到日志表里去String target = arg2.getClass().getName();String methodName = arg0.getName();String args = Arrays.toString(arg1);System.out.println("【前置通知:系统日志】:"+target+"."+methodName+"("+args+")被调用了");}}

1.5配置系统通知XML中的JavaBean

<!--通知--><bean class="com.YU.aop.advice.MyMethodBeforeAdvice" id="myMethodBeforeAdvice"></bean>

1.6 配置代理XML中的JavaBean

<!-- 代理--><bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy"><!-- 配置目标对象 --><property name="target" ref="bookBiz"></property><!-- 配置代理接口,目标对象的接口 --><property name="proxyInterfaces"><value>com.YU.aop.biz.IBookBiz</value></property><property name="interceptorNames"><list><value>myMethodBeforeAdvice</value></list></property></bean>

1.7 测试代码开始测试

package com.YU.aop.test;import com.YU.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author YU* @create 2023-08-17 15:14*/
public class Test1 {public static void main(String[] args) {//建模ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//        IBookBiz bookBiz = (IBookBiz) context.getBean("bookBiz");IBookBiz bookBiz = (IBookBiz) context.getBean("bookProxy");bookBiz.buy("死仔","我的26岁女房客",18.8d);bookBiz.comment("死仔","真好看");}
}

测试结果:

 由测试结果可得知,不仅获取到了我们的参数,同时根据方法获取到了我们的系统日志,也就是前置通知

2. 后置通知

2.1 先准备好后置通知的系统日志

package com.zking.aop.advice;import java.lang.reflect.Method;
import java.util.Arrays;import org.springframework.aop.AfterReturningAdvice;/*** 买书返利* @author Administrator**/
public class MyAfterReturningAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {String target = arg3.getClass().getName();String methodName = arg1.getName();String args = Arrays.toString(arg2);System.out.println("【后置通知:买书返利】:"+target+"."+methodName+"("+args+")被调用了,"+"该方法被调用后的返回值为:"+arg0);}}

2.2 配置后置系统通知的XML的JavaBean

<!--后置通知--><bean class="com.YU.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>

并在前面已经配置好的代理接口中添加一个value值

 2.3 测试结果

 由测试结果我们可以得知,后置通知永远都在方法执行后才会显示通知,与前置通知不同的是每次前面的方法调用后都会返回一个参数

3.环绕通知

3.1 环绕通知就是前置通知和后置通知的结合,在实际应用开发中,我们一般不会单独编写前置通知和后置通知,单独使用前置通知或者后置通知时,我们会使用环绕通知,将里面前置(后置)通知的功能注释,以达到单独使用的目的

3.2 环绕通知的系统日志

package com.YU.aop.advice;import java.util.Arrays;import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;/*** 环绕通知* 	包含了前置和后置通知* * @author Administrator**/
public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation arg0) throws Throwable {String target = arg0.getThis().getClass().getName();String methodName = arg0.getMethod().getName();String args = Arrays.toString(arg0.getArguments());System.out.println("【环绕通知调用前:】:"+target+"."+methodName+"("+args+")被调用了");
//		arg0.proceed()就是目标对象的方法Object proceed = arg0.proceed();System.out.println("【环绕通知调用后:】:该方法被调用后的返回值为:"+proceed);return proceed;}}

3.3 配置环绕通知的XML的JavaBean与前置通知和后置通知一致

3.4 测试结果

 

由测试结果得知,环绕通知就是前置通知和后置通知的结合,优点就是不需要再多次去进行配置及编码,所以就像我们前面所说在实际开发应用中我们一般都会选择使用环绕通知

4.异常通知

4.1 异常通知的系统日志和其他系统日志不同的是,方法名为固定的afterThrowing,不能修改

package com.YU.aop.advice;import org.springframework.aop.ThrowsAdvice;import com.YU.aop.exception.PriceException;/*** 出现异常执行系统提示,然后进行处理。价格异常为例* @author Administrator**/
public class MyThrowsAdvice implements ThrowsAdvice {public void afterThrowing(PriceException ex) {System.out.println("【异常通知】:当价格发生异常,那么执行此处代码块!!!");}
}

4.2 在我们正常程序出问题没有去配置异常通知时会出现报错,并且不会执行后面的后置通知,如以下情况

4.3 异常处理配置和前面的配置相同

4.4 当我们配置好异常通知模块时,程序出现异常时会上报日志进行提示

5.过滤通知

5.1 直接在XML中配置JavaBean

<!--过滤通知--><bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="regexpMethodPointcutAdvisor"><property name="advice" ref="myAfterReturningAdvice"></property><property name="pattern" value=".*buy"></property></bean>

 

将图中指出部分替换成过滤通知

 测试结果:

对比框中内容,在调用过buy方法后进行过滤,第二次调用时不再buy方法而是comment方法 

四.总结

aop是面向切面编程,普通程序由上而下正常执行,aop的程序执行是先执行到目标对象的目标方法中,如果连接点上由前置通知,则先执行前置通知再执行目标方法,最后如果目标方法有后置通知则最后执行后置通知代码,不管是前置通知,后置通知,环绕通知,异常通知,过滤通知,代码都是非业务核心代码,如日志、事务的管理(开启、提交、回滚)         

相关文章:

Spring-aop特点,专业术语及案例演示

一.aop简介 AOP&#xff08;Aspect-Oriented Programming&#xff09;是Spring框架的一个重要特性&#xff0c;它通过将横切关注点&#xff08;cross-cutting concerns&#xff09;从核心业务逻辑中分离出来&#xff0c;以模块化的方式在整个应用程序中重复使用。以下是关于AOP…...

探秘Java的Map集合:键值映射的奇妙世界

文章目录 1. 单列集合 vs. 双列集合2. Map接口&#xff1a;键与值的契约3. 深入探索HashMap3.1 特性与构造方法3.2 常用方法3.3 遍历HashMap 4. 美妙的LinkedHashMap 在Java编程中&#xff0c;集合是不可或缺的重要部分&#xff0c;它为我们提供了各种数据结构和算法的实现。其…...

git权限问题解决方法Access denied fatal: Authentication failed

文章目录 遇到Access denied 的权限问题解决方法1、git的密码修改过&#xff0c;但是本地没更新。2、确定问题&#xff0c;然后增加配置① 查询用户信息②如果名称和email不对&#xff0c;设置名称&#xff1a;③ 检查ssh-add是否链接正常④ 设置不要每次都输入用户名密码 3、配…...

Hands on RL 之 Off-policy Maximum Entropy Actor-Critic (SAC)

Hands on RL 之 Off-policy Maximum Entropy Actor-Critic (SAC) 文章目录 Hands on RL 之 Off-policy Maximum Entropy Actor-Critic (SAC)1. 理论基础1.1 Maximum Entropy Reinforcement Learning, MERL1.2 Soft Policy Evaluation and Soft Policy Improvement in SAC1.3 Tw…...

JavaScript中的this指向,call、apply、bind的简单实现

JavaScript中的this this是JavaScript中一个特殊关键字&#xff0c;用于指代当前执行上下文中的对象。它的难以理解之处就是值不是固定的&#xff0c;是再函数被调用时根据调用场景动态确定的&#xff0c;主要根据函数的调用方式来决定this指向的对象。this 的值在函数被调用时…...

Linux学习之基本指令一

在学习Linux下的基本指令之前首先大家要知道Linux下一切皆目录&#xff0c;我们的操作基本上也都是对目录的操作&#xff0c;这里我们可以联想我们是如何在windows上是如何操作的&#xff0c;只是形式上不同&#xff0c;类比学习更容易理解。 目录 01.ls指令 02. pwd命令 0…...

appium默认60秒关闭应用的问题

问题&#xff1a;appium默认启动一个应用的session过期时间是60秒到时间会自动停了刚启动的应用&#xff0c;工作台打印&#xff1a;info: [debug] We shut down because no new commands came in的日志 分析&#xff1a;--command-timeout 60 The default command timeout fo…...

Docker 容器内无法使用vim命令 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 进入Docker容器后 无法使用vim编辑器,出现如下问题:bash: vim: command not found 如图所示: 想着通过apt-get 安装vim,出现如下问题: root@b9f0fd330d5b:/# apt-get install vim Reading package lists... Done B…...

Django的简介安装与配置及两大设计模式

一.Djang的介绍 1.Django是什么 Django 是使用 Python 语言开发的一款免费而且开源的 Web 应用框架。 由于 Python 语言的跨平台性&#xff0c;所以 Django 同样支持 Windows、Linux 和 Mac 系统。 在 Python 语言炽手可热的当下&#xff0c;Django 也迅速的崛起&#xff0c;在…...

Mybatis分页插件——PageHelper

一、定义 PageHelper用在mybatis插件里面&#xff0c;可以自动的为最近的sql语句进行分页查询&#xff0c;提供分页的页码size和每页数量num&#xff0c;在查询过程中hi自动的拼接limit关键字&#xff0c;不用再改写sql语句了 在PageHelper.startPage()&#xff1b; 在启动查询…...

k8s认证详解 k8s证书详解 2023推荐

推荐阅读 https://www.yii666.com/blog/478731.html?actiononAll 在 Kube-apiserver 中提供了很多认证方式&#xff0c;其中最常用的就是 TLS 认证&#xff0c;当然也有 BootstrapToken&#xff0c;BasicAuth 认证等&#xff0c;只要有一个认证通过&#xff0c;那么 Kube-api…...

php初解

php是什么&#xff1f; PHP&#xff0c;全称 Hypertext Preprocessor &#xff0c;中文翻译“超文本预处理器”。 PHP是一种被广泛应用的开源通用脚本语言&#xff0c;尤其适用于 Web 开发。 拥有快速&#xff0c;灵活&#xff0c;实用的特点&#xff0c;PHP能做任何事&#xf…...

【C语言】回调函数,qsort排序函数的使用和自己实现,超详解

文章目录 前言一、回调函数是什么二、回调函数的使用1.使用标准库中的qsort函数2.利用qsort函数对结构体数组进行排序 三、实现qsort函数总结 先记录一下访问量突破2000啦&#xff0c;谢谢大家支持&#xff01;&#xff01;&#xff01; 这里是上期指针进阶链接&#xff0c;方便…...

PHP手术麻醉系统源码,自动生成麻醉和护理医疗文书

一套手术麻醉系统源码&#xff0c;可二次开发 手术室麻醉临床信息系统&#xff08;AIMS&#xff09;是应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进行全程跟踪与信息管理&#xff0c;自动集成病人HIS、LIS、RIS、PACS信息&#xff0…...

内网穿透实战应用——【通过cpolar分享本地电脑上有趣的照片:发布piwigo网页】

通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页 文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页前言1. 设定一条内网穿透数据隧道2. 与piwigo网站绑定3. 在创建隧道界面填写关键信息4. 隧道创建完成 总结 前言 首先在本地电脑上部署…...

iPhone删除的照片能恢复吗?不小心误删了照片怎么找回?

iPhone最近删除清空了照片还能恢复吗&#xff1f;大家都知道&#xff0c;照片对于我们来说是承载着美好回忆的一种形式。它记录着我们的平淡生活&#xff0c;也留住了我们的美好瞬间&#xff0c;具有极其重要的纪念价值。 照片不小心误删是一件非常难受的事&#xff0c;那么iP…...

LeetCode--HOT100题(32)

目录 题目描述&#xff1a;138. 复制带随机指针的链表&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;138. 复制带随机指针的链表&#xff08;中等&#xff09; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &…...

SAP MM学习笔记24-以评估收货(评价)和非评估收货(非评价)

SAP 中 有评价入库&#xff08;评估收货&#xff09;和非评价入库&#xff08;非评估收货&#xff09;两种入库方式。 一般来说在库品目会采用评价入库&#xff0c;而消费品目&#xff0c;会采用非评价入库。 其实评价入库&#xff0c;非评价入库对外都无所谓的&#xff0c;人…...

Hadoop的DataNode无法启动的解决方案

Hadoop重启一次&#xff0c;里面的数据需要重新导入&#xff0c;发现无法导入数据&#xff0c;查看jps发现是DataNode没有启动&#xff0c;重新启动发现也无法启动&#xff0c;原因是前面重新启动NameNode&#xff0c;里面的文件格式化一次&#xff0c;DataNode的文件不一致&am…...

re中的match和search有什么区别?

问题:请说明以下re模块中的match和search有什么区别? re.match()与re.search()的区别 re.match()只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,结果返回None,而re.search()匹配整个字符串,直到找到一个匹配 re.search() re.search()扫描整个字符串并…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.

这个警告表明您在使用Vue的esm-bundler构建版本时&#xff0c;未明确定义编译时特性标志。以下是详细解释和解决方案&#xff1a; ‌问题原因‌&#xff1a; 该标志是Vue 3.4引入的编译时特性标志&#xff0c;用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...