Spring AOP详解,简单Demo

目录

一、Spring AOP 是什么?

二、学习AOP 有什么作用?

三、AOP 的组成

四、 Spring AOP 简单demo


一、Spring AOP 是什么?

Spring AOP(Aspect-Oriented Programming in Spring)是Spring框架中的一个重要组件,它实现了面向切面编程(AOP)的思想。AOP是一种编程范式,旨在通过预编译方式和运行期动态代理实现程序功能的统一维护。它利用一种称为“切面”(Aspect)的技术,将那些与业务逻辑无关,却为多个业务逻辑所共同调用的逻辑或责任(例如事务处理、日志记录、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可维护性和可拓展性。

在Spring AOP中,切面被定义为一个包含通知(Advice)和切点(Pointcut)的对象。通知是切面的实际行为,它定义了切面要执行的操作,如前置通知(Before Advice)、后置通知(After Advice)、环绕通知(Around Advice)等。切点则定义了通知应该应用于哪些连接点(Joinpoint),连接点是程序执行过程中能够应用通知的位置,如方法调用、异常抛出等。

Spring AOP主要使用代理模式来实现AOP的功能。当Spring容器启动时,它会根据配置或注解创建代理对象,这些代理对象会拦截对目标对象的调用,并在调用前后或调用过程中执行相应的通知逻辑。这样,在不修改原有目标对象代码的情况下,我们可以动态地为目标对象添加额外的功能或行为。

总的来说,Spring AOP提供了一种灵活且强大的机制,使得开发者能够更加方便地处理那些跨越多个类或方法的横切关注点,从而提高代码的可维护性和可扩展性。

二、学习AOP 有什么作用?

学习AOP(面向切面编程)的作用主要体现在以下几个方面:

  1. 解耦业务逻辑与横切关注点:在软件开发中,经常有一些与业务逻辑无关但却横跨多个模块的功能需求,如日志记录、事务管理、安全性控制等。这些横切关注点会散布在代码的各个角落,导致业务逻辑与这些关注点紧密耦合,难以维护。AOP通过将这些横切关注点从业务逻辑中分离出来,使代码更加清晰、整洁,便于管理和维护。

  2. 提高代码重用性和模块化:AOP允许开发者将通用的功能逻辑封装成切面,然后在需要的地方进行引用。这样,相同的逻辑只需要编写一次,就可以被多个模块复用,大大提高了代码的重用性和模块化程度。

  3. 降低代码复杂性:通过将横切关注点从业务逻辑中分离出来,AOP可以简化业务逻辑的代码,使其更加专注于实现核心功能。同时,AOP还提供了强大的连接点模型,允许开发者精确地控制通知的执行时机和范围,进一步降低了代码的复杂性。

  4. 增强系统的可扩展性和可维护性:由于AOP将横切关注点与业务逻辑分离,因此当需要修改或添加新的横切关注点时,只需要修改或添加相应的切面即可,而不需要修改业务逻辑代码。这大大增强了系统的可扩展性和可维护性。

  5. 统一处理异常和错误:AOP可以帮助我们统一处理异常和错误,例如在一个切面中定义异常处理的逻辑,然后在多个地方引用这个切面。这样,当程序抛出异常时,我们可以自动记录日志、发送通知或执行其他操作,而不需要在每个可能抛出异常的地方都编写相同的处理代码。

  6. 支持跨方法的逻辑:AOP能够处理跨多个方法的逻辑,这对于一些需要在多个方法之间共享状态或执行共同操作的场景非常有用。。

三、AOP 的组成

3.1、切面(Aspect)

切面是AOP的核心概念,它定义了横切关注点的逻辑。切面由通知(Advice)和切点(Pointcut)组成,它既包含了横切关注点的定义,也包含了何时将这些横切关注点应用到目标对象上的逻辑。

 3.2、切点(Pointcut)

切点用于定义切面要通知的具体连接点。一个切面并不需要通知应用的所有连接点,切点有助于缩小切面所通知的连接点范围。切点使用特定的语法来描述,以确定哪些连接点应该被通知。

切点相当于保存了众多连接点的一个集合(如果把切点看成一个表,而连接点就是表中一条一条的数 据)。

3.3、通知(Advice) 

通知就是 AOP 的具体执行动作。具体的,在程序中被拦截后会触发一个具体的动作,就是通知中具体实现的业务代码

定义了切面是什么,何时使用,其描述了切面要完成的工作,还解决何时执行这个工作的问题。 Spring 切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件后会通知本方法进行调 用 

  • 前置通知使用 @Before:通知方法会在(该注解的value)切入目标方法调用之前执行。
  • 后置通知使用 @After: 通知方法会在(该注解的value)切入目标方法返回或者抛出异常之后调用。
  • 返回之后通知使用 @AfterReturning: 通知方法会在目标方法正常执行完毕之后调用
  • 抛异常后通知使用 @AfterThrowing: 通知方法会在目标方法抛出异常后调用。
  • 环绕通知使用 @Around:设置指定的通知处理方法(该注解的value)切入到目标方法前后执行,功能约等于@Before+@AfterReturning。

3.4、连接点

会触发 AOP 规则的所有的点(所有请求)。

四、 Spring AOP 简单demo

4.1、添加 Spring AOP  框架依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

4.2、定义切面

@Aspect //告诉spring 这是一个切面类
@Component
public class AopConfig {
}

4.3、定义切点

@Aspect //告诉spring 这是一个切面类
@Component
public class AopConfig {//切点@Pointcut("execution(* com.zcm.Demo.controller.*.*(..))")public void pointcut() {}}
@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
  1. @Pointcut: 这是一个注解,用于定义一个切点。切点是AspectJ中用于确定哪些连接点(如方法调用、异常处理等)应该被通知(advice)或拦截的表达式。

  2. "execution( com.example.demo.controller.UserController.(..))"**: 这是切点的表达式。它的含义如下:

    • execution(): 表示我们正在匹配方法执行。
    • *: 表示匹配任何返回类型。
    • com.example.demo.controller.UserController: 表示我们只想匹配com.example.demo.controller.UserController这个类中的方法。
    • .*: 表示匹配UserController中的任何方法名。
    • (..): 表示匹配任何数量的参数,无论参数的类型和数量如何。

4.4、定义通知

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Aspect //告诉spring 这是一个切面类
@Component
public class AopConfig {//切点@Pointcut("execution(* com.zcm.Demo.controller.*.*(..))")public void pointcut(){}@Before("pointcut()")public void beforeAdvice(){System.out.println("执行了前置通知");}@After("pointcut()")public void afterAdvice(){System.out.println("执行了后置通知");}/*** 环绕通知* @param joinPoint* @return* @throws Throwable*/@Around("pointcut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("进入了环绕通知~");String str = joinPoint.proceed().toString();String newStr = str.substring(0, 8);System.out.println("退出了环绕通知~");return newStr;}}

 执行结果

进入了环绕通知~
执行了前置通知
userTest方法执行了
aop执行了
执行了后置通知
退出了环绕通知~

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

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

相关文章

Go 学习笔记

Go 学习相关笔记 Go 官方的教学文档顺序不怎么友好&#xff0c;这里根据我自己的学习曲线来记录文档的查看顺序 基础知识 文档预备 新手先要看 Go 的模块管理介绍&#xff0c;这样才知道基础 Go 怎么导入外部包和进行本地的包管理 https://go.dev/doc/modules/managing-dep…

C语言贪吃蛇项目

今天给大家带来一款简单的贪吃蛇游戏&#xff0c;一起随我来看看吧 游戏效果&#xff1a; 实现基本的功能&#xff1a; • 贪吃蛇地图绘制 • 蛇吃⻝物的功能&#xff1a;&#xff08;上、下、左、右⽅向键控制蛇的动作&#xff09; • 蛇撞墙死亡 • 蛇撞⾃⾝死亡 • 计算得分…

Linux-进程间通信(进程间通信介绍、匿名管道原理及代码使用、命名管道原理及代码使用)

一、进程通信介绍 1.1进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某…

【Android】SharedPreferences阻塞问题深度分析

前言 Android中SharedPreferences已经广为诟病&#xff0c;它虽然是Android SDK中自带的数据存储API&#xff0c;但是因为存在设计上的缺陷&#xff0c;在处理大量数据时很容易导致UI线程阻塞或者ANR&#xff0c;Android官方最终在Jetpack库中提供了DataStore解决方案&#xf…

spring的高阶使用技巧1——ApplicationListener注册监听器的使用

Spring中的监听器&#xff0c;高阶开发工作者应该都耳熟能详。在 Spring 框架中&#xff0c;这个接口允许开发者注册监听器来监听应用程序中发布的事件。Spring的事件处理机制提供了一种观察者模式的实现&#xff0c;允许应用程序组件之间进行松耦合的通信。 更详细的介绍和使…

Kubernetes 声明式语言 YAML

什么是 YAML YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一种可读的数据序列化语言&#xff0c;通常用于配置文件、数据序列化和交换格式。YAML 的设计目标是易读易写&#xff0c;并且能够映射到动态语言中的数据结构 YA加粗样式ML 是 JSON 的超集&#xff0…

HFSS19 官方案例教程W03 - SMA接头与微带分支

SMA接头与微带分支 1►射频接头简介 连接器是电子测量中必不可少的重要部件,无论测试仪表还是DUT,无论线缆还是附件,处处都有形形色色的不同连接器的身影。对于射频工程师而言,经常用到的连接器有N型、BNC型、SMA型、3.5 mm、2.92 mm、2.4 mm、1.85 mm、1 mm这几种 (上…

CSS学习(选择器、盒子模型)

1、CSS了解 CSS&#xff1a;层叠样式表&#xff0c;一种标记语言&#xff0c;用于给HTML结构设置样式。 样式&#xff1a;文字大小、背景颜色等 p标签内不能嵌套标题标签。 px是相对于分辨率而言的&#xff0c; em是相对于浏览器的默认字体&#xff0c; rem是相对于HTML根元…

【MySQL】MVCC的实现原理

【MySQL】MVCC的实现原理 MVCC简介事务的隔离级别读未提交&#xff08;Read Uncommitted&#xff09;概念分析 读已提交&#xff08;Read Committed&#xff09;概念分析结论 可重复读&#xff08;Repeatable Read&#xff09;概念分析结论 串行化&#xff08;Serializable &am…

Java调用接口获得图片输入流InputStream并返回给前端

效果&#xff1a; 代码&#xff1a; export const getPhotoById params > get(${base}/weda/myLecture/poster/template/getPhotoById?id${params.id}&isPreview${params.isPreview},{}); // 获取原始的大图后端 Overridepublic void getPhotoById(PosterTemplate dt…

三、VUE数据代理

一、初识VUE 二、再识VUE-MVVM 三、VUE数据代理 Object.defineProperty() Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性&#xff0c;或修改其现有属性&#xff0c;并返回此对象。 Object.defineProperty() 数据代理 通过一个对象代理另一个对象中属…

【启明智显技术分享】关于工业级HMI芯片Model3C的TEXT RODATA,必须要映射到PSRAM吗?

一、Model3C芯片介绍 Model3C芯片性能 Model3C&#xff08;简称M3C&#xff09;是一款基于 RISC-V 的高性能、国产自主、工业级高清显示与智能控制 MCU&#xff0c;配备强大的 2D 图形加速处理器、PNG/JPEG 解码引擎、丰富的接口&#xff0c;支持工业宽温&#xff0c;具有高…