Spring之AOP理解与应用

news2024/11/19 12:42:51

1. AOP的认识    

 面向切面编程:基于OOP基础之上新的编程思想,OOP面向的主要对象是类,而AOP面向的主要对象是切面,在处理日志、安全管理、事务管理等方面有非常重要的作用。AOP是Spring中重要的核心点,AOP提供了非常强大的功能,用来对IOC做补充。通俗点说的话就是在程序运行期间,在不修改原有代码的情况下 增强跟主要业务没有关系的公共功能代码到 之前写好的方法中的指定位置 这种编程的方式叫AOP。

        AOP在Spring框架中被用于:

  1. 提供声明式的企业服务。最重要的此类服务是 声明式事务管理。
  2. 让用户实现自定义切面,用AOP补充他们对OOP的使用。 

2. AOP核心概念和术语 

2.1 切面(Aspect)

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

2.2  连接点(Join point)

         在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总是代表一个方法的执行。

2.3  通知(Advice)

         在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”, “before” and “after”等等。通知的类型将在后面的章节进行讨论。 许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。

前置通知(Before advice): 在连接点之前运行但无法阻止执行流程进入连接点的通知(除非它引发异常)。

后置返回通知(After returning advice):在连接点正常完成后执行的

通知(例如,当方法没有抛出任何异常并正常返回时)。

后置异常通知(After throwing advice): 在方法抛出异常退出时执行的通知。

后置通知(总会执行)(After (finally) advice): 当连接点退出的时候执行的通知(无论是正常返回还是异常退出)。

环绕通知(Around Advice):环绕连接点的通知,例如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它可以选择是否继续执行连接点或直接返回自定义的返回值又或抛出异常将执行结束。

2.4 切点(Pointcut)

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

2.5 引入(Introduction)

         声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例如,可以使用引入来使bean实现 IsModified接口, 以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明(inter))。

2.6 目标对象(Target object)

         被一个或者多个切面所通知的对象。也被称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现的,那么这个对象永远是一个被代理(proxied)的对象。

2.7 AOP代理(AOP proxy)

        AOP框架创建的对象,用来实现切面契约aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

2.8 织入(Weaving)

        把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP框架一样,是在运行时完成织入的。

3. 一图理解AOP核心概念

        本节是个人对照业务需求对AOP的一些概念的解读。

        我们通过一个场景和一张图通俗的理解一下AOP的切面、通知、连接点和切入点这几个概念;

        场景: 我们有一个日志类,有before()、after()、AfterException()、afterReturn()这几个方法,我们需要记录我们的方法的日志,如果不适用AOP,那么我们就得在每个方法的前面、后面、异常调用这个日志类的方法。如果使用AOP呢? 我们如何理解呢?

        理解:

        切面指的是关注点模块化,那么我们抽出来的日志类是不是就可以理解为一个切面呢?

        切面和我们的业务方法连接的点就是连接点

        通知是运行在连接点上的动作,那么抽出来的这个日志类的方法是不是就可以理解为通知呢?

        切点是匹配连接点的断言,那就是说我们指定哪些需要增强的搭连接点就是切点

        

4. AOP的应用场景

  • 日志管理
  • 权限认证
  • 安全检查
  • 事务控制

5. 如何使用AOP

        本节会通过AOP实现日志记录的需求进行演示如何使用AOP;本案例使用的是基于注解使用AOP;

第一步: 配置AOP的依赖

     <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

第二步:开启扫面注解

   <!--扫描包:扫描类中所有注解,不扫描注解不是生效-->
    <context:component-scan base-package="cn.learn.aop" >
    </context:component-scan>

    <!--因为我们使用的是注解方式的AOP,所以要开启注解AOP功能-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

第三步: 编写切面类

@Aspect    // 标记为切面
@Component // 标记Bean组件, 才能切入到ioc当中的bean
public class LogAspect {

    // 可以采用 声明切点的方式 让其他通知引用, 更重用性
    @Pointcut("execution(* cn.myLearnAop.service.impl.*.*(..))")
    public void pointcut(){

    }

    // 前置通知
    @Before("pointcut()")
    public void before(JoinPoint joinPoint, Logger logger){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();

        System.out.println(logger.name()+"方法运行,参数是:"+ Arrays.asList(args)+"注解的值是:");
    }

    // 后置通知
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();
        System.out.println(methodName+"方法运行,参数是:"+ Arrays.asList(args));
    }
    // 后置异常通知
    @AfterThrowing(value="pointcut()",
                   throwing="ex")
    public void afterThrowing(Exception ex){
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw, true));
        System.out.println("后置异常通知"+sw.getBuffer().toString());
    }
    // 后置返回通知
    @AfterReturning(value="pointcut()",
                    returning = "returnValue")
    public void afterReturning(Object returnValue){
        System.out.println("返回值:"+returnValue);
    }


    // 环绕
    @Around("pointcut()")
    public  Object arround(ProceedingJoinPoint joinPoint){
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();

        Object returnValue="";
        try {
            System.out.println("环绕:前置通知:"+methodName+"方法执行,参数:"+Arrays.asList(args));
            returnValue=joinPoint.proceed();
            System.out.println("环绕:后置通知:"+methodName+"方法执行,参数:"+Arrays.asList(args));
        } catch (Throwable throwable) {
            System.out.println("环绕:异常通知:"+throwable);
        }
        finally {
            System.out.println("环绕:返回通知:"+returnValue);
        }

        return returnValue;
    }

}

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

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

相关文章

【已解决】为什么Word文档里有部分内容无法编辑?

小伙伴们是否遇到过这样的情况&#xff0c;打开Word文档进行编辑&#xff0c;发现部分内容可正常编辑&#xff0c;另外一部分内容却无法编辑。这是怎么回事&#xff0c;又要如何解决呢&#xff1f; 出现以上情况&#xff0c;一般是Word文档被设置了“限制保护”&#xff0c;使…

【文末送书】Python OpenCV从入门到精通

文章目录 &#x1f354;简介opencv&#x1f339;内容简介&#x1f6f8;编辑推荐&#x1f384;导读&#x1f33a;彩蛋 &#x1f354;简介opencv OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;提供了丰富的图像处理和…

第1章 理解知识图谱:知识图谱现状、知识图谱应用场景(二)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

css实现正六边形嵌套圆心

要实现一个正六边形嵌套圆心&#xff0c;可以使用CSS的::before和::after伪元素以及border-radius属性。以下是具体的解析和代码&#xff1a; 使用::before和::after伪元素创建正六边形。设置正六边形的背景色。使用border-radius属性使正六边形的内角为60度。在正六边形内部创…

Uber Go 语言编码规范

uber-go/guide 的中文翻译 English 文档链接 Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司&#xff0c;也是 Go 语言的早期 adopter。其开源了很多 golang 项目&#xff0c;诸如被 Gopher 圈熟知的 zap、jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 G…

Spatial Data Analysis(一):线性回归

Spatial Data Analysis&#xff08;一&#xff09;&#xff1a;线性回归 来源&#xff1a;https://github.com/Ziqi-Li/GEO4162C/tree/main 在此示例中&#xff0c;我们将介绍如何在 python 中拟合线性回归模型。 我们将使用的数据集是 2020 年县级选举投票数据以及来自 ACS …

STM32单片机项目实例:基于TouchGFX的智能手表设计(1)项目介绍及GUI界面基础

STM32单片机项目实例&#xff1a;基于TouchGFX的智能手表设计&#xff08;1&#xff09;项目介绍及GUI界面基础 一、项目介绍 1.1方案提供 1.2主控选择 1.3硬件平台 1.4 开发环境 1.5 关于华清 二、GUI界面基础 2.1.1 嵌入式绘图系统 2.1.1 色彩格式 2.1.1帧缓冲区 …

ERP软件定制开发对企业的优势|app小程序搭建

ERP软件定制开发对企业的优势|app小程序搭建 随着科技的不断发展&#xff0c;企业管理也面临了更多的挑战。为了更好地适应市场需求和提高运营效率&#xff0c;越来越多的企业开始选择使用ERP软件进行管理。然而&#xff0c;市场上现成的ERP软件并不能完全满足企业的需求&#…

css 修改滚动条样式,解决Windows浏览器中滚动条不美观问题

Windows环境中的浏览器中滚动条默认是直接显示了&#xff0c;不管光标是否进入该区域&#xff0c;这样就很不美观&#xff0c;如下图&#xff1a; 之前样式为 .well {display: block;background-color: #f2f2f2;border: 1px solid #ccc;margin: 5px;width: calc(100% - 12px);h…

HarmonyOS/OpenHarmony应用开发

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目, 目标是面向全场景、全连接、全智能时代, 搭建一个智能终端设备操作系统的框架和平台, 促进万物互联产业的繁荣发展。 了解OpenHarmony HarmonyOS是华为通过OpenHarmony项目&#xff0c;结合商业…

调试GMS应用,报错“此设备未获得play保护机制认证”问题解决

不少同学在调试GMS相关应用时&#xff0c;需登录Google账号&#xff0c;有时会弹出如下通知。 Google登录界面也会出现如下提示 这个报错的原因是设备未通过Google认证&#xff0c;google服务器未配置荣耀设备的型号白名单导致 国内网页有一些指导方法在鸿蒙\荣耀的设备上消除这…

2023年江西省“振兴杯”网络信息行业职业技能竞赛 Web4 Writeup

这次振兴杯碰到的一道题&#xff0c;某些姿势之前貌似没有碰过&#xff0c;简单记一下吧 源码 <?php class Bird{public $funcs;public $salt;public $flag;function say_flag(){$secret hash_hmac(sha256, $_GET[salt], file_get_contents(/flag));$hmac hash_hmac(sha…

BearPi Std 板从入门到放弃 - 引气入体篇(5)(printf打印到串口)

简介 基于 BearPi Std 板从入门到放弃 - 引气入体篇&#xff08;4&#xff09;(Usart 中断接收), 使用printf打印到串口 步骤 覆写fputc函数 需要添加头文件#include “stdio.h” /* USER CODE BEGIN 0 */ int fputc(int ch, FILE *f) {uint8_t temp[1] {ch};{HAL_UART_Tr…

服务器托管与服务器租用的详细比较

​  在当今数字化时代&#xff0c;服务器托管和服务器租用成为了许多企业和个人选择的两种常见方式。它们都提供了一种将服务器放置在专业机房中的解决方案&#xff0c;但在具体实施和使用过程中存在一些差异。下面将详细比较这两种方式的优势和劣势。 1. 服务器托管 服务器托…

Python机器学习、深度学习入门丨气象常用科学计算库、气象海洋常用可视化库、爬虫和气象海洋数据、气象海洋常用插值方法、EOF统计分析、WRF模式后处理等

目录 专题一 Python软件的安装及入门 专题二 气象常用科学计算库 专题三 气象海洋常用可视化库 专题四 爬虫和气象海洋数据 专题五 气象海洋常用插值方法 专题六 机器学习基础理论和实操 专题七 机器学习的应用实例 专题八 深度学习基础理论和实操 专题九 深度学习的应…

力扣543. 二叉树的直径(java DFS解法)

Problem: 543. 二叉树的直径 文章目录 题目描述思路解题方法复杂度Code 题目描述 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们…

ubuntu20.04使用LIO-SAM对热室空间进行重建

一、安装LIO-SAM 1.环境配置 默认已经安装过ros sudo apt-get install -y ros-Noetic-navigation sudo apt-get install -y ros-Noetic-robot-localization sudo apt-get install -y ros-Noetic-robot-state-publisher 安装 gtsam(如果是18.04的ubuntu直接按照官网配置&…

[C国演义] 第二十三章

第二十三章 两个字符串的最小ASCLL删除和最长重复子数组 两个字符串的最小ASCLL删除和 力扣链接 求 删除字符的ASCLL和的最小值 ⇒ 正难则反 ⇒ 求公共子序列的ASCLL和的最大值 两个数组的dp问题 ⇒ 分区间讨论 ⇒ dp[i][j] -- nums1数组的[0, i] 区间 和 nums2数组的[0, j] …

文字转语音、语音转文字! AI视频生成神器!

分享一波文字转语音、语音转文字&#xff01;AI视频生成神器&#xff01;让外国人说中文&#xff0c;口型自然&#xff0c;不限语言&#xff0c;感兴趣的同学可以试试~ 可以用Al生成视频&#xff0c;Whisper语音转文字 Whisper 开源项目&#xff1a; https://github.com/Const…

【算法】Boyer-Moore 算法

目录 1.概述1.1.Boyer-Moore 算法介绍1.2.坏字符规则表1.3.好后缀规则表1.4.总结 2.代码实现3.应用 更多数据结构与算法的相关知识可以查看数据结构与算法这一专栏。 有关字符串模式匹配的其它算法&#xff1a; 【算法】Brute-Force 算法 【算法】KMP 算法 【算法】Rabin-Karp …