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

【Spring】19 AOP介绍及实例详解

文章目录

    • 1. 定义
      • 1)什么意思呢?
      • 2)如何解决呢?
    • 2. 基本概念
      • 1)切面(Aspect)
      • 2)切点(Pointcut)
      • 3)通知(Advice)
      • 4)连接点(Join Point)
      • 5)织入(Weaving)
    • 3. 例子
      • 1)添加依赖
      • 2)定义一个测试类
      • 3)创建切面
      • 4)创建启动类
      • 5)运行应用程序
    • 4. 将 [基本概念] 和 [例子] 结合解释说明
    • 总结

Spring 框架提供了强大的面向切面编程(AOP)支持,使得我们能够更方便的实现横切关注点的功能,比如日志记录、事务管理等。本文将深入探讨 Spring AOP 的概念、原理以及如何在应用程序中应用 AOP。

1. 定义

AOP 是一种编程范式,它允许将横切关注点与业务逻辑分离。横切关注点是那些跨足多个模块的关注点,比如日志、事务、方法执行时间等。通过 AOP 我们可以在不修改原始业务逻辑代码的情况下,将这些关注点模块化。

1)什么意思呢?

概念往往都是让人读不懂的,接下来让我们来举例说明一下:

首先看看我们的需求是什么呢?我们在实际开发过程中会写了无数个方法,想在每个方法开头和结束打印一下日志,例如某某方法开始了和某某方法结束了。

如下图这样:

在这里插入图片描述

是不是可以很清晰的发现一个问题,有无数个方法我们就需要在无数个方法里面分别加上这两个代码。。。

2)如何解决呢?

使用 AOP 面向切面编程,统一来一下。这就好像我们想把一些纸剪成两半似的,一张一张的剪就很慢(和上面现象一样),我们可以给它们摞起来然后用剪刀一刀下去,咔!全部剪开(AOP面向切面编程)。

就变成了下图这样:

在这里插入图片描述

是不是突然发现爽歪歪啦!

2. 基本概念

1)切面(Aspect)

切面是一种模块化的单元,它包含了横切关注点的实现,在 Spring AOP 中,切面是由切点和通知组成的。

2)切点(Pointcut)

切点定义了在何处应用切面的规则,它是一个表达式,用于匹配连接点(在应用中执行的特定代码位置),切点决定了切面在哪里生效。

3)通知(Advice)

通知是切面的具体实现,它定义了在何时、何地、以及如何应用切面的逻辑。常见的通知类型包括前置通知、后置通知、异常通知、最终通知和环绕通知。

4)连接点(Join Point)

连接点是在应用中执行的特定代码位置,如方法调用、方法执行、异常抛出等,它是切点的实际执行实例。

5)织入(Weaving)

织入是将切面应用到目标对象并创建代理对象的过程。织入可以在编译时、类加载时、运行时进行。

3. 例子

1)添加依赖

pom.xml 中添加 spring-aopaspectjweaver 两个依赖(这里只写了本次新添加的两个)

        <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.20.1</version></dependency>

2)定义一个测试类

创建一个简单的业务类,例如 DemoController ,其中包含一个待切入的方法

package com.cheney.koala.controller;import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {public void print(){System.out.println("Hello");}
}

3)创建切面

创建一个切面类,例如 LoggingAspect ,用于定义在方法执行前后打印日志的通知

package com.cheney.koala.aspect;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Pointcut("execution( * com.cheney.koala.controller.*.*(..) )")public void demoActionExecution() {}@Before("demoActionExecution()")public void logBefore(JoinPoint joinPoint) {System.out.println("方法 " + joinPoint.getSignature().getName() + " 开始啦");}@After("demoActionExecution()")public void logAfter(JoinPoint joinPoint) {System.out.println("方法 " + joinPoint.getSignature().getName() + " 结束啦");}
}

在这个切面中,我们使用 @Aspect 注解标识这是一个切面类。

@Pointcut("execution( * com.cheney.koala.controller.*.*(..) )") 这句代码是一个 Spring AOP 中的切点表达式,用于定义在哪些方法上应用切面。

  • @Pointcut:这是一个注解,用于定义切点,即在哪些方法上应用切面
  • execution:这是切点表达式的一部分,表示匹配方法的执行
  • *:这是通配符,表示匹配任意返回类型的方法
  • com.cheney.koala.controller:这是包名,表示匹配该包下的所有类
  • *.*(..):这也是通配符,表示匹配该包下所有类的所有方法

因此,整个表达式的意思就是匹配 com.cheney.koala.controller 包下所有类的所有方法,无论返回类型和参数类型是什么,都是我想切的对象(也即前后加入方法开始和方法结束的日志)

@Before@After 注解的通知方法中,使用 JoinPoint 获取连接点信息,包括方法签名等

4)创建启动类

KoalaApplication.java 中,添加了默认启动后调用 DemoController 里的 print 方法,仅仅是为了测试方便,没有别的特殊用意。

package com.cheney.koala;import com.cheney.koala.controller.DemoController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class KoalaApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(KoalaApplication.class, args);DemoController demo = context.getBean(DemoController.class);demo.print();}
}

5)运行应用程序

运行应用程序,你将看到如下输出

在这里插入图片描述

方法 print 开始啦
Hello
方法 print 结束啦

这表明我们成功地通过 AOP 切面在方法执行前后分别打印了日志

4. 将 [基本概念] 和 [例子] 结合解释说明

在这里插入图片描述

  • **切面 **

    使用 @Aspect 注解标识这是一个切面类。在类中使用 @Pointcut 注解定义了一个切点 demoActionExecution,用于匹配我想切的对象

  • 切点

    execution( * com.cheney.koala.controller.*.*(..) ) 表示 com.cheney.koala.controller 包下所有类的所有方法,无论返回类型和参数类型是什么,都是我想切的对象

  • 连接点

    使用 JoinPoint 获取连接点信息,包括方法签名等

  • 通知

    使用 @Before@After 注解定义了两个通知方法,分别在方法执行前后执行

  • 织入

    在运行时,Spring AOP 将切面织入目标对象的方法中,从而在方法执行前后执行通知

总结

通过 Spring AOP,我们能够将关注点(如日志记录)与业务逻辑分离,使得代码更加清晰、可维护。在实际应用中,AOP 可以应用于诸如事务管理、安全性、性能监控等方面,为应用程序提供更高的可扩展性和可维护性。本文通过一个日志打印的例子,详细介绍了在 Spring AOP 中切面、切点、通知、连接点和织入的概念,并成功地使用 AOP 实现了在方法执行前后分别打印日志的功能。这种方式帮助我们实现了横切关注点的代码重用,提高了代码的可维护性和可读性,也希望通过本文的介绍,可以将 AOP 应用到具体项目开发中。

相关文章:

【Spring】19 AOP介绍及实例详解

文章目录 1. 定义1&#xff09;什么意思呢&#xff1f;2&#xff09;如何解决呢&#xff1f; 2. 基本概念1&#xff09;切面&#xff08;Aspect&#xff09;2&#xff09;切点&#xff08;Pointcut&#xff09;3&#xff09;通知&#xff08;Advice&#xff09;4&#xff09;连…...

ES(Elasticsearch)的基本使用

一、常见的NoSQL解决方案 1、redis Redis是一个基于内存的 key-value 结构数据库。Redis是一款采用key-value数据存储格式的内存级NoSQL数据库&#xff0c;重点关注数据存储格式&#xff0c;是key-value格式&#xff0c;也就是键值对的存储形式。与MySQL数据库不同&#xff0…...

【JVM面试题】Java中的静态方法为什么不能调用非静态方法

昨晚京东大佬勇哥在群里分享了一道他新创的JVM面试题&#xff0c;我听完后觉得还挺有意思的&#xff0c;分享给大家 小佬们先别急着看我的分析&#xff0c;先自己想想答案 你是不是想说 因为静态方法是属于类的&#xff0c;而非静态方法属于实例对象 哈&#xff0c;有人这样回答…...

对‘float16_t’的引用有歧义

float16_t 是一个半精度浮点数类型&#xff0c;通常在一些需要高性能和低精度的场合被使用。 如果加了using namespace cv;后&#xff0c;OpenCV库中也有一个名为float16_t的类型定义&#xff0c;与最初的float16_t存在冲突&#xff0c;导致编译失败。 为了解决这个问题&#…...

Windows重装升级Win11系统后 恢复Mysql数据

背景 因为之前电脑硬盘出现问题&#xff0c;换了盘重装了系统&#xff0c;项目的数据库全部没了&#xff0c;还好之前的Mysql是安装在的D盘里&#xff0c;还有留存文件 解决办法 1.设置环境变量 我的路径是 D:\SoftWare\Application\mysql-5.7.35-winx64 此电脑右键属性 …...

MySQL之四大引擎、账号管理以及建库

目录 数据库存储引擎 简介 存储引擎得查看 support字段说明 InnoDB MyISAM MEMORY Archive 数据库管理 元数据库简介 元数据库分类 相关操作 MySQL库 数据表管理 三大范式 基本数据类型 优化原则 整形 实数 字符串 text&blob 日期类型 选中标识符 数…...

shell编程——查找局域网内存活主机

题目要求&#xff1a;写一个shell脚本&#xff0c;探测局域网内存活主机 首先&#xff0c;我们的思路是在循环中不断ping主机&#xff0c;然后根据ping的结果来判断主机是否存活 本题中ping语句如下&#xff1a; ping -c 3 -i 0.3 -W 1 192.168.1.1 解释一下参数&#xff1…...

python django 个人记账管理系统

python django 个人记账管理系统。 功能&#xff1a;登录&#xff0c;新用户注册&#xff0c;个人信息修改&#xff0c;收入&#xff0c;支出记录&#xff0c;收入记账管理&#xff0c;支出记账管理&#xff0c;收入&#xff0c;支出统计 技术&#xff1a;python django&…...

C#的Char 结构的方法之IsLetterOrDigit()

目录 一、Char 结构 二、Char.IsLetterOrDigit 方法 1.定义 2.重载 3.示例 4.IsLetterOrDigit(Char) 5.IsLetterOrDigit(String, Int32) 一、Char 结构方法 CompareTo(Char)将此实例与指定的 Char 对象进行比较&#xff0c;并指示此实例在排序顺序中是位于指定的 Char …...

配置Docker私有仓库

# 打开要修改的文件 vi /etc/docker/daemon.json # 添加内容&#xff1a; "insecure-registries":["http://自己服务器的ip地址:设置的端口号"] # 重加载 systemctl daemon-reload # 重启docker systemctl restart docker在自己设定的文件夹内使用DockerCo…...

计算机网络-动态路由

网络层协议&#xff1a;ip&#xff0c;ospf&#xff0c;rip&#xff0c;icmp共同组成网络层体系 ospf用于自治系统内部。 一个路由器或者网关需要能够支持多个不同的路由协议&#xff0c;以适应不同的网络环境。特别是在连接不同自治系统的边缘路由器或边界网关的情况下&#…...

光耀未来 第一届能源电子产业创新大赛太阳能光伏赛道决赛在宜宾举行

1月3日&#xff0c;第一届能源电子产业创新大赛太阳能光伏赛道决赛在宜宾盛大举行&#xff0c;本次比赛吸引了全国范围内的光伏行业顶尖人才和创新团队参与。 为深入贯彻《关于推动能源电子产业发展的指导意见》&#xff0c;推动我国能源电子产业升级&#xff0c;工业和信息化部…...

【小沐学NLP】Python实现TF-IDF算法(nltk、sklearn、jieba)

文章目录 1、简介1.1 TF1.2 IDF1.3 TF-IDF2.1 TF-IDF(sklearn)2.2 TF-IDF(nltk)2.3 TF-IDF(Jieba)2.4 TF-IDF(python) 结语 1、简介 TF-IDF&#xff08;term frequency–inverse document frequency&#xff09;是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Fr…...

.cer格式证书文件和 .pfx格式证书文件有什么区别?

这里我们将讨论.cer和.pfx文件类型之间的差异。 什么是数字证书&#xff1f; 数字证书在电子通信中用作验证身份的密码机制。我们需要这些证书来建立安全的在线通信渠道&#xff0c;并确保数字数据的隐私、真实性和正确性。 数字证书包括主题&#xff08;实体详细信息&#xf…...

【docker实战】安装tomcat并连接mysql数据库

本节用docker来安装tomcat&#xff0c;并用这个tomcat连接我们上一节安装好的mysql数据库 一、拉取镜像 我们安装8.5.69版本 先搜索一下 [rootlocalhost ~]# docker search tomcat NAME DESCRIPTION …...

LeetCode 每日一题 Day 32 ||递归单调栈

2487. 从链表中移除节点 给你一个链表的头节点 head 。 移除每个右侧有一个更大数值的节点。 返回修改后链表的头节点 head 。 示例 1&#xff1a; 输入&#xff1a;head [5,2,13,3,8] 输出&#xff1a;[13,8] 解释&#xff1a;需要移除的节点是 5 &#xff0c;2 和 3 。…...

【mars3d】FixedRoute的circle没有跟polyline贴着模型的解决方案

问题&#xff1a;【mars3d】官网的贴模型示例中&#xff0c;参考api文档增加了circle的配置&#xff0c;但是FixedRoute的circle没有跟polyline贴着模型 circle: { radius: 10, materialType: mars3d.MaterialType.CircleWave, materialOptions: { color: "#ffff00"…...

Day7 vitest 之 vitest配置第三版

项目目录 runner Type: VitestRunnerConstructor Default: node, 当运行test的时候 benchmark,当运行bench测试的时候 功能 自定义测试运行程序的路径。 要求 应与自定义库运行程序一起使用。 如果您只是运行测试&#xff0c;则可能不需要这个。它主要由library作者使用 …...

git补充上次提交

1.首先&#xff0c;确保你还没有执行 git push 操作。如果尚未推送到远程仓库&#xff0c;那么可以在本地进行修正。 2.添加遗漏的文件&#xff1a; git add <遗漏的文件路径>3.提交新修改或新增的文件&#xff0c;并将它与上一次提交合并&#xff08;如果希望保持提交历…...

计算机网络名词解释

1.ICMP 网际控制报文 允许主机或路由器报告差错情况和提供有关异常情况的报告 2.RIP路由信息协议 是一种分布式的&#xff0c;基于距离向量的路由选择协议 3.BGP 外部网关协议 是不同自治系统的路由器之间交换路由信息的协议 4.IGMP 网际管理协议 使用多播路由器知道多播…...

flink table view datastream互转

case class outer(f1:String,f2:Inner) case class outerV1(f1:String,f2:Inner,f3:Int) case class Inner(f3:String,f4:Int) 测试代码 package com.yy.table.convertimport org.apache.flink.streaming.api.scala.StreamExecutionEnvironment import org.apache.flink.tabl…...

redis重启后数据丢失问题解决(亲测好用)

redis修改密码重启后发现redis中的数据丢失了 解决办法&#xff1a; 首先在redis的安装目录下查找重启之前的dump.rdb文件&#xff0c;发现只有当天的一个dump.rdb文件&#xff0c;确认不是重启备份的文件 然后我就全盘找一下dump.rdb的备份文件&#xff0c;找到前一天的备份…...

敬请期待……

敬请期待…… 《Python百宝箱》 序号文章目录直达链接表白系列1无法拒绝的表白界面https://want595.blog.csdn.net/article/details/1347448942满屏飘字表白代码https://want595.blog.csdn.net/article/details/1350373883无限弹窗表白代码...

3.10 Android eBPF HelloWorld调试(四)

一,读取eBPF map的android应用程序示例 1.1 C++源码及源码解读 /system/memory/bpfmapparsed/hello_world_map_parser.cpp //基于aosp android12#define LOG_TAG "BPF_MAP_PARSER"#include <log/log.h> #include <stdlib.h> #include <unistd.h&g…...

PyTorch常用工具(1)数据处理

文章目录 前言1 数据处理1.1 Dataset1.2 DataLoader 前言 在训练神经网络的过程中需要用到很多的工具&#xff0c;最重要的是数据处理、可视化和GPU加速。本章主要介绍PyTorch在这些方面常用的工具模块&#xff0c;合理使用这些工具可以极大地提高编程效率。 由于内容较多&am…...

docker-简单说说cgroup

前面我们简单说了下namespace&#xff0c; 现在我们来接着简单说说cgroup。通过docker-简单说说namespace文章我们知道&#xff1a; namespace 是为了隔离进程组之间的资源&#xff0c;那cgroup就是为了对进程组的监控和限制资源。Cgroup 可以限制进程组使用的资源数量和分配&a…...

印象笔记04: 如何将印象笔记超级会员价值最大化利用?

印象笔记04&#xff1a; 如何将印象笔记超级会员价值最大化利用&#xff1f; 为什么有这个问题 我不知道有没有人一开始接触印象笔记觉得非常好。奈何只能两个设备同步&#xff0c;局限太多。而会员活动比较优惠——就开了会员。而且我开了十年……。只能开发一下看看怎么最大…...

我的JDK动态代理流程

我的JDK动态代理流程 我梳理的动态代理流程大约是&#xff1a; 如果每一个框架都有自己的BPP&#xff0c;且自己的BPP中都有自己的wrapIfNecessory&#xff0c;那样可能就是一个BPP一个代理类。但通常应该都是各自的框架以提供 Advisior&#xff08;切面&#xff09;的方式&am…...

uniapp Vue3 面包屑导航 带动态样式

上干货 <template><view class"bei"><view class"container"><view class"indicator"></view><!-- 遍历路由列表 --><view v-for"(item, index) in routes" :key"index" :class&quo…...

openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作

文章目录 openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作174.1 事务隔离说明174.2 写入和读写操作174.3 并发写入事务的潜在死锁情况 openGauss学习笔记-174 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作 174.1 事务隔离说…...

专门做儿童的店铺网站/制作一个小型网站

Service&#xff08;服务&#xff09;是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service&#xff0c;并且当用户切换到另外的应用场景&#xff0c;Service将持续在后台运行。另外&#xff0c;一个组件能够绑定到一个service与之交互&#xf…...

评估企业网站建设/龙岩seo

第1章 计算机硬件原理与基本工作原理目录第1章计算硬件组成与基本工作原理... 41.1 计算机组成... 41.2 计算机工作原理... 5第2章服务器-----加强版的电脑... 52.1 加强版... 52.2 作为运维人员--职责... 52.3 衡量服务器尺寸... 52.4 服务器组成... 62.5 服务器的品牌... 62.…...

通过做政府门户网站的实验获得什么/手机百度登录入口

1、首先进入mysql的安装目录下的bin目录&#xff0c;例如我的是【C:\WINDOWS\System32\cmd.exe】2、接着输入cmd&#xff0c;回车3、在命令行中输入命令【mysql -hlocalhost -uroot -p 按回车键&#xff0c;输入密码】&#xff0c;其中【-h主机名 -u用户 -p密码】 4、成功进入界…...

网页设计实训内容/seo营销推广公司

转载于:https://www.cnblogs.com/jasonlixuetao/p/5557845.html...

web网站开发实训总结/品牌推广的概念

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/qq_34173549/article/details/81158566 定义问题 外部排序指的是大文件的排序&#xff0c;即待排序的记录存储在外存储器上&#xff0c;待排序的文件无法一次装入内存&#x…...

电脑网站打不开是什么原因造成的/网络推广网站建设

http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx ——————————————————————————————————————————————————————————————————...