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

【Spring】初识 Spring AOP(面向切面编程)

目录

1、介绍AOP

1.1、AOP的定义

1.2、AOP的作用

1.3、AOP的核心概念及术语

2、AOP实现示例

3、@EnableAspectJAutoProxy注解

1、介绍AOP

1.1、AOP的定义

        AOP(Aspect Orient Programming),直译过来就是面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如Spring的事务,通过事务的注解配置,Spring会自动在业务方法中开启、提交业务,并且在业务处理失败时,执行相应的回滚策略。

1.2、AOP的作用

作用:AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。

主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。

简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。

AOP的经典应用场景有:日志记录、事务管理、权限验证、性能监测

AOP可以拦截指定的方法,并且对方法增强,比如:事务、日志、权限、性能监测等增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离。

1.3、AOP的核心概念及术语

目标对象(Target):目标对象指将要被增强(比如增强功能)的对象,或者说被一个或多个切面所通知的对象,即包含主业务逻辑的类的对象,即为目标对象。

可以说要增强的对象(通常会有很多个)就是目标对象

切面(Aspect):指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schema-basedapproach)或者在普通类中以@Aspect注解(@Aspect注解方式)来实现。

可以说增强代码放入的那个类就叫切面类,由@Aspect注解来标识

通知(Advice):在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”,“before” 和“after”等等。通知的类型将在后面详细了解。许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。

用来放增强的代码的那个方法就是通知

  • 环绕通知@Around:可以把代码增强在目标方法的任意地方,更通用
  • 前置通知@Before:目标方法之前执行
  • 后置通知@After:目标方法之后执行
  • 异常通知@AfterThrowing:目标方法出现了异常执行
  • 返回通知@AfterReturning:目标方法返回值执行

切点(Pointcut):匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用Aspectj切点语义。

增强代码要对哪些类中的哪些方法进行增强,进行切割,指的是被增强的方法,即要切哪些东西。切点表达式

连接点(Join point):在Spring AOP中,一个连接点总是代表一个方法的执行,其实就代表增强的方法。

连接点就是通知和目标方法的一个桥梁,可以获取到目标方法的信息,就得通过JoinPoint

顾问(Advisor):顾问是Advice的一种包装体现,Advisor是Pointcut以及Advice的一个结合,用来管理Advice和Pointcut。应用无需关心.

顾问是源码中的体现,会封装切点和通知

织入(Weaving):将通知切入连接点的过程叫织入,就是我这个增强代码织入到目标方法或者叫切入到目标方法都可以

2、AOP实现示例

        假设有一个类的所有业务功能都已经实现,但是最后我想在所有的功能里面加一个公共的功能(记录所有的请求的用时), 这时候就可以利用AOP来实现,切面就是(需要增强的公共的、跟业务没有关系的公共代码)。可以在不改变原有业务代码的基础上进行了增强。所以面向切面编程往往让我们的开发更加低耦合,也大大减少了代码量,同时呢让我们更专注于业务模块的开发,把那些与业务无关的东西提取出去,便于后期的维护和迭代。

如何在Spring中创建一个所谓切面?

切面里面的代码怎么运行在业务方法(运行在之前、运行在之后)

使用AOP需要引入依赖

<!--以spring-boot-starter为前缀的依赖都是springboot官方提供的依赖,
不需要自己来指定版本,因为parent都帮我们管理好了,
springboot通过这种方式统一管理了版本,可以减少版本的冲突-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

aspectj:AOP概念并不是spring独家提出来的,AOP早就有成熟框架已经实现了,aspectj就是一个成熟的AOP的解决方案,spring只不过是把aspectj集成进来了

AOP实现示例代码:@Aspect注解可以把一个类标记为切面类

自定义类UserService,假设其所有业务功能(增删查改)都已经实现,但是我想给这些功能加一个记录请求用时的功能。这时用AOP来实现

//自定义类UserService,假设其所有业务功能都已经实现
@Service
public class UserService {// 增加增删改查方法,这里就用一个打印语句来代替具体的方法功能了public void add(){System.out.println("增加");}public void delete(){System.out.println("删除");}public void update(){System.out.println("修改");}public void query(){System.out.println("查询");}
}//切面类LogAspect,通过这个切面类来实现在所有的功能里面加一个公共的功能(记录所有的请求的用时)
@Aspect  //把这个类标记为切面类
@Component  //切面类必须声明为Spring的bean
public class LogAspect, {// execution(* com.lt.UserService.*(..)) 切点表达式// @Around 环绕通知@Around("execution(* com.lt.UserService.*(..))") //切点表达式public void log(ProceedingJoinPoint proceedingJoinPoint){//记录方法用时long begin = System.currentTimeMillis();// 执行具体的方法try {proceedingJoinPoint.proceed();} catch (Throwable e){System.out.println("方法执行异常:" + e.getMessage());}long end = System.currentTimeMillis();System.out.println("方法用时:" + (end - begin) + "ms");}}//测试类C4AopApplicationTests
@SpringBootTest(classes = C4AopApplicationTests.class)
@ComponentScan
class C4AopApplicationTests {@Testvoid contextLoads(@Autowired UserService userService) {userService.add();}}

运行结果:

3、@EnableAspectJAutoProxy注解

1、@EnableAspectJAutoProxy:启用AOP,没有这个注解AOP功能无法使用

如果要使用SpringAOP的功能,必须要添加一个@EnableAspectJAutoProxy注解,有了这个注解才能支持@Aspect等相关的一系列AOP注解的功能,这个注解就相当于在传统的xml配置文件中添加 <aop:aspectj-autoproxy>一样。

2、@EnableAspectAutoProxy不是一定要加的

比如上面的AOP示例,为什么没有加@EnableAspectJAutoProxy注解,AOP也起作用了?

这是因为SpringBoot其实会通过启动类自动帮我们加上@EnableAspectJAutoProxy,所以可以省略。(@SpringBootApplication这个注解帮我们做了很多的事情,包括自动帮我们加上@EnableAspectJAutoProxy注解)

//测试类C4AopApplicationTests
@SpringBootTest(classes = C4AopApplicationTests.class)
@ComponentScan
class C4AopApplicationTests {......
}//启动类
@SpringBootApplication // 由于这个注解起了作用,所以自动加了@EnableAspectJAutoProxy
public class C4AopApplication {......
}

所以com.lt包下的启动类C4AopApplication和他上面的上面的注解@SpringBootApplicatio也会被扫描到,由于这个注解起了作用,所以自动加了@EnableAspectJAutoProxy

但是依然建议加上@EnableAspectJAutoProxy,因为在Spring中没有这个注解AOP功能会无法使用。

 推荐:

【Spring】IOC/DI中常用的注解@Lazy、@Scope与@Conditional-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/138277932?spm=1001.2014.3001.5501

【Spring】IOC/DI中常用的注解@Order与@DependsOn-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/138167160?spm=1001.2014.3001.5501

【spring】Bean的生命周期回调函数和Bean的循环依赖-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/138503989?spm=1001.2014.3001.5501

相关文章:

【Spring】初识 Spring AOP(面向切面编程)

目录 1、介绍AOP 1.1、AOP的定义 1.2、AOP的作用 1.3、AOP的核心概念及术语 2、AOP实现示例 3、EnableAspectJAutoProxy注解 1、介绍AOP 1.1、AOP的定义 AOP&#xff08;Aspect Orient Programming&#xff09;&#xff0c;直译过来就是面向切面编程&#xff0c;AOP 是一…...

k8s各个组件的作用

Kubernetes&#xff08;K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化计算机容器化应用程序的部署、扩展和管理。以下是 Kubernetes 中的关键组件及其作用&#xff1a; API 服务器&#xff08;API Server&#xff09;&#xff1a; 作为集群中所有资源操作的入…...

Spring Cloud 整合Sentinel

1、引入依赖 版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 父pom <spring.cloud.version>Hoxton.SR12</spring.cloud.version> <spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>Sentinel应用直接引用starter <…...

Java入门基础学习笔记4——开发Helloworld入门程序

Java程序开发的三个步骤&#xff1a; 1&#xff09;编写代码 2&#xff09;编译代码 3&#xff09;运行代码 注意事项&#xff1a; 第一个java程序建议使用记事本来编写。 建议代码文件名全英文、首字母大写、满足驼峰模式&#xff0c;源代码文件的后缀必须是.java 注意&a…...

了解WebSocket

1.概念&#xff1a; WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;属于应用层协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握…...

从开发角度理解漏洞成因(02)

文章目录 文件上传类需求文件上传漏洞 文件下载类需求文件下载漏洞 扩展 留言板类&#xff08;XSS漏洞&#xff09;需求XSS漏洞 登录类需求cookie伪造漏洞万能密码登录 持续更新中… 文章中代码资源已上传资源&#xff0c;如需要打包好的请点击PHP开发漏洞环境&#xff08;SQL注…...

Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点

文章目录 一、通信机制1、轮询1.1、短轮询1.2、长轮询 2、Websocket3、Server-Sent Events 二、区别1、连接方式2、协议3、兼容性4、安全性5、优缺点5.1、WebSocket 的优点&#xff1a;5.2、WebSocket 的缺点&#xff1a;5.3、SSE 的优点&#xff1a;5.4、SSE 的缺点&#xff1…...

TMS320F280049 CLB模块--LUT4 OUTLUT(4)

LUT4 示意图如下&#xff1a; OUTLUT 示意图如下&#xff1a; 寄存器 参考文档&#xff1a; TMS320F28004x Real-Time Microcontrollers Technical Reference Manual (Rev. G)...

功能测试_分类_用例_方法

总结 测试分类 按阶段分类 是否查看源代码分类 是否运行分类 是否自动化 其他分类 软件质量模型 开发模型-瀑布模型 测试过程模型 v w 测试用例八大要素 用例编号 用例标题 …...

[沫忘录]MySQL 锁

[沫忘录]MySQL 锁 锁能够协调多线程或多进程并发访问某资源产生的数据冲突与错乱。而在数据库中&#xff0c;锁也是协调数据库访问的有效工具。 全局锁 能够锁住当前服务器所有数据库及其表。后续所有事务都只能进行读操作&#xff0c;而不能进行写操作或表属性更改。 典型…...

噪声嵌入提升语言模型微调性能

在自然语言处理&#xff08;NLP&#xff09;的快速发展中&#xff0c;大模型&#xff08;LLMs&#xff09;的微调技术一直是研究的热点。最近&#xff0c;一篇名为《NEFTUNE: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING》的论文提出了一种新颖的方法&#xff0c;通过在训…...

XML文档基本语法

XML文档基本语法包括以下几个知识点&#xff1a; 开始标记&#xff08;Start Tag&#xff09;&#xff1a;开始标记是XML元素的起始符号&#xff0c;由左尖括号&#xff08;<&#xff09;和元素名称组成。例如&#xff0c;是一个开始标记&#xff0c;表示一个名为"book…...

git开发工作流程

git开发工作流程 &#xff08;1&#xff09;先将远程代码pull到本地 &#xff08;2&#xff09;在本地上分支上进行开发 &#xff08;3&#xff09;开发完之后&#xff0c;push到远程分支 &#xff08;4&#xff09;由远程的master进行所有分支合并...

JDK生成https配置

keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:\https证书\weChat.keystore -validity 36500 -keypass 250250 keytool -importkeystore -srcstoretype JKS -srckeystore D:\https证书\weChat.keystore -srcstorepass 250250 -srcalias tomcat -srckeypass 25025…...

通过 Java 操作 redis -- set 集合基本命令

目录 使用命令 sadd &#xff0c;smembers 使用命令 sismember 使用命令 scard 使用命令 spop 使用命令 sinter&#xff0c;sinterstore&#xff0c;sunion&#xff0c;sunionstore&#xff0c;sdiff&#xff0c;sdiffstore 关于 redis set 集合类型的相关命令推荐看Redis …...

WebSocket前后端建立以及使用

1、什么是WebSocket WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久化的连接&#xff0c;允许服务器主动向客户端推送数据&#xff0c;同时也允许客户端向服务器发送数据&#xff0c;实现了实时的双向通信。 这部分直接说你可能听不懂&#xff1b;我…...

C++数据结构之链表树图的存储

本文主要介绍用数组存储&#xff0c;结构只做简单介绍 目录 文章目录 前言 结构体实现 1、链表的存储 2、树的存储 3、图的存储 数组实现 1、链表实现 2、树和图的实现 总结 前言 在正常工程中&#xff0c;我们通常使用结构体或者类&#xff0c;来定义并使用如链表…...

又一位互联网大佬转行当网红,能写进简历么?

最近半个月&#xff0c;有两个中年男人仿佛住进了热搜。 一个是刚刚辟谣自己“卡里没有冰冷的 40 亿”的雷军&#xff0c;另一个则是在今年年初就高呼“如果有可能&#xff0c;企业家都要去当网红”的 360 创始人周鸿祎。 他也确实做到了。 先是作为当年 3Q 大战的当事人&…...

Codeforces Round 134 (Div. 1) A. Ice Skating (并查集)

Ice Skating 题面翻译 Description 给出n个点的横纵坐标&#xff0c;两个点互通当且仅当两个点有相同的横坐标或纵坐标&#xff0c;问最少需要加几个点才能使得所有点都两两互通 Input 第一行一个整数n表示点数&#xff0c;之后n行每行两个整数x[ i ]和y[ i ]表示第i个点的…...

深入了解 Flask Request

文章目录 获取请求数据获取请求信息文件上传总结 Flask 是一个轻量级的 Python Web 框架&#xff0c;其简洁的设计和灵活的扩展性使其成为了许多开发者的首选。在 Flask 中&#xff0c;处理 HTTP 请求是至关重要的&#xff0c;而 Flask 提供了丰富而强大的 request 对象来处理…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...

计算机系统结构复习-名词解释2

1.定向&#xff1a;在某条指令产生计算结果之前&#xff0c;其他指令并不真正立即需要该计算结果&#xff0c;如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方&#xff0c;那么就可以避免停顿。 2.多级存储层次&#xff1a;由若干个采用不同实现技术的存储…...

AT模式下的全局锁冲突如何解决?

一、全局锁冲突解决方案 1. 业务层重试机制&#xff08;推荐方案&#xff09; Service public class OrderService {GlobalTransactionalRetryable(maxAttempts 3, backoff Backoff(delay 100))public void createOrder(OrderDTO order) {// 库存扣减&#xff08;自动加全…...