Spring AOP详解,简单Demo

news2024/11/25 6:33:46

目录

一、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.coloradmin.cn/o/1634632.html

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

相关文章

preg_match详解(反向引用和捕获组)

在讲preg_match函数之前&#xff0c;我们先了解一下什么是php可变变量 php可变变量 在PHP中双引号包裹的字符串中可以解析变量&#xff0c;而单引号则不行 也就是在php中&#xff0c;双引号里面如果包含有变量&#xff0c;php解释器会将其替换为变量解释后的结果&#xff1b…

基于 SpringCloud 的在线交易平台乐优商城的设计与实现(三)

基于 SpringCloud 的在线交易平台乐优商城的设计与实现 第3章 系统分析与设计3.1 系统基本功能描述3.2 可行性分析3.3 系统需求分析3.3.1 商家功能3.3.2 消费者功能&#xff1a;3.3.3 系统功能要求3.3.4 系统运行环境 3.4 系统开发工具3.4.1 IntellijIDEA3.4.2 Mysql3.4.3 Mave…

C/C++ 入门(9)编译链接

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 目录 一、域 1、分类 2、搜索顺序 二、编译链接 1、代码在形成可执行文件的过程 2、符号表 三、问题 1、带有缺省参数的函数声明和定义分离 一、域 1、分类 域&#xff1a;全局域、局部域、命…

第12章 消息服务

第12章 消息服务 12.1 JMS1. 简介2. ActiveMQ安装Linux安装命令 3. 整合SpringBoot ****************************************************** 12.1 JMS 1. 简介 2. ActiveMQ安装 Linux安装命令 //下载 wget http://mirrors.hust.edu.cn/apache/activemq/5.15.16/apache-acti…

JAVA系列 小白入门参考资料 类和对象(2)

目录 小引 1. this this引用 this的特性 this的使用 2. 对象的构造及初始化 如何初始化对象 构造方法 利用构造方法初始化对象的三种方式 方式一 方式二 方式三 直接初始化 小引 上一篇文章我们讨论到 如果创立类和对象&#xff0c;并且如何实例化对象和怎样…

Vue+Element UI el-progress进度条内显示自定义数字及文字

需求 进度条内展示 具体的数字值&#xff0c;进度条外展示 百分比数值 数据 data() {return {reNum: 3214,rePer:40,warmPer: 40,warmNum:2132,}}因为样式要求&#xff0c;显示的百分数也是自己写的哈 &#xff0c;没有用进度条自带的 代码 <div class"pick"&g…

Java学习3:程序流程控制

Java程序流程控制 1.执行顺序 顺序结构分支顺序 if,switch 循环结构 for ,while ,do-while 2.if分支 三种形式 if(条件表达式){} else if(){} else{}3.switch分支 string week "周一"; switch(week){case "周一":stem.out.println("周一&qu…

六西格玛黑带考试:一场心灵与智慧的较量

终于踏过了六西格玛黑带考试这座大山&#xff0c;心中的激动与释然如波涛汹涌。这场考试&#xff0c;不仅仅是对我知识的检验&#xff0c;更是对我毅力与决心的考验。 备考的日子里&#xff0c;我仿佛进入了一个全新的世界。从统计学的深邃到流程优化的细致&#xff0c;每一个…

C++入门第二节

点赞关注不迷路&#xff01;&#xff0c;本节涉及c入门关键字、命名空间、输入输出... 1. C关键字 C总计63个关键字&#xff0c;C语言32个关键字 asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenam…

在STM32上实现嵌入式人工智能应用

引言 随着微控制器的计算能力不断增强&#xff0c;人工智能&#xff08;AI&#xff09;开始在嵌入式系统中扮演越来越重要的角色。STM32微控制器由于其高性能和低功耗的特性&#xff0c;非常适合部署轻量级AI模型。 本文将探讨如何在STM32平台上实现深度学习应用&#xff0c;…

【活动】AIGC 技术的发展现状与未来趋势

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 AIGC 技术的发展现状与未来趋势引言AIGC技术的发展现状文本生成图像生成音频生成…

Git中单独的功能特性分支是什么含义

在Git中&#xff0c;一个"功能特性分支"&#xff08;通常简称为“特性分支”&#xff09;是指从主开发分支&#xff08;比如main或master&#xff09;独立出来的分支&#xff0c;专门用于开发一个新功能、修复一个bug&#xff0c;或者进行实验性的尝试。使用特性分支…

【Python BUG】connect: permission denied.

问题描述 解决方案 本质是权限问题 sudo密码即可

​基于Python的在线自主评测系统(django)​

基于Python的在线自主评测系统(django) 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 学生功能模块的实现 学生注册的实现 学生登录界面首页 在线考试界面 考试成绩查看界面 教师功能模块的实现 新建…

用什么模型算法可以预测足球胜平负

预测足球胜平负的模型算法有很多种&#xff0c;每种算法都有其特点和适用场景。以下是一些常见的模型算法&#xff1a; Elo预测法&#xff1a; 这是一种通过研究主客场球队在比赛前的积分情况来预测胜负的方法。Elo预测法通过计算两队之间的积分差&#xff0c;根据特定的公式&…

工业互联网通讯协议—欧姆龙(Fins tcp)

一、场景 近期公司要对欧姆龙CP系列设备的数据采集&#xff0c;于是就研究了下欧姆龙的Fins Tcp协议。 二、Fins Tcp 组成字节说明固定头446494E53 FINS对应的ASCII码的十六进制长度4后面剩余指令的长度命令4 握手固定为&#xff1a;00000000 读写固定为&#xff1a;0000000…

http 协议的状态码有哪些?含义是什么?

http 协议的状态码有哪些&#xff1f;含义是什么&#xff1f; 一、http 协议的状态码类别二、常见的http 协议状态码及其含义 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; http 协议是互联网上应用最为广泛的协议之一&#xff0c;而http …

力扣HOT100 - 22. 括号生成

解题思路&#xff1a; class Solution {List<String> res new ArrayList<>();public List<String> generateParenthesis(int n) {if (n < 0) return res;getParenthesis("", n, n);return res;}private void getParenthesis(String str, int …

基于FPGA的数字信号处理(2)--什么是定点数?

在实际的工程应用中&#xff0c;往往会进行大量的数学运算。运算时除了会用到整数&#xff0c;很多时候也会用到小数。而我们知道在数字电路底层&#xff0c;只有「高电平1」和「低电平0」的存在&#xff0c;那么仅凭 0和1 该如何表示小数呢&#xff1f; 数字电路中&#xff0…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.3--Cortex-A7寄存器介绍

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…