关于Spring Aop的通知类型

在这里插入图片描述

一、概述

1.1 通知类型

  为了符合各种流程处理,通知类型提供了5种,可以对目标方法进行全方位处理,如下所示:

通知类型说明
前置通知(Before advice)在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
后置通知(After returning advice)在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
异常通知(After throwing advice)在方法抛出异常退出时执行的通知。
最终通知(After advice)当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice)包围一个连接点的通知,如方法调用。

  Spring提供所有类型的通知,个人推荐使用尽可能简单的通知类型来实现需要的功能。例如,如果只是需要一个方法的返回值来更新缓存,最好使用后置通知而不是环绕通知,尽管环绕通知也能完成同样的事情。用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的错误。比如,不需要在JoinPoint上调用用于环绕通知的proceed()方法,就不会有调用的问题。
  我们把这些术语串联到一起,方便理解,如下图所示:

在这里插入图片描述

1.2 @AspectJ支持

  @AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。Spring 使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器。为了在Spring配置中使用@AspectJ切面,首先必须启用Spring对@AspectJ切面配置的支持。

@Aspect
@Component
public class WebLogAspect {}

在Spring AOP中,拥有切面的类本身不可能是其它切面中通知的目标。一个类上面的 @Aspect 注解标识它为一个切面,并且从自动代理中排除它。

二、声明通知

  通知是跟一个切入点表达式关联起来的,并且在切入点匹配的方法执行之前或者之后或者前后运行。切入点表达式可能是指向已命名的切入点的简单引用或者是一个已经声明过的切入点表达式。和XML方式的通知不同的是,注解通知采取在切面类的通知方法上面直接加上相应注解即可。主要有:@Before、@After、@AfterReturning、@AfterThrowing、@Around等5个注解。

2.1 前置通知

  一个切面里使用 @Before 注解声明前置通知,其在目标类的方法执行之前执行,比如用于拦截记录用户的操作。在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。

@Aspect
@Component
public class WebLogAspect {@Beforepublic void doBefore(JoinPoint joinPoint) {}
}

上面的前置通知方法中用的了JoinPoint参数,在通知方法中可以声明一个JoinPoint类型的参数。通过JoinPoint可以访问连接点的细节。它的常用方法包括:

参数说明
java.lang.Object[] getArgs()获取连接点方法运行时的入参列表
Signature getSignature()获取连接点的方法签名对象
java.lang.Object getTarget()获取连接点所在的目标对象
java.lang.Object getThis()获取代理对象本身
java.lang.Object proceed()通过反射执行目标对象的连接点处的方法
java.lang.Object proceed(java.lang.Object[] args)通过反射执行目标对象连接点处的方法,不过使用新的参数替换原来的参数。

2.2 后置返回通知

  后置返回通知,当目标方法执行成功后执行该方法体,使用 @AfterReturning 注解来声明。正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行。

@Aspect
@Component
public class WebLogAspect {@AfterReturningpublic void doAfterReturning(JoinPoint joinPoint, Object keys) {}
}

2.3 异常通知

  当目标方法抛出异常返回后,执行该方法体,使用 @AfterThrowing 注解来声明。

@Aspect
@Component
public class WebLogAspect {@AfterThrowingpublic void doAfterThrowing(JoinPoint joinPoint, Throwable exception) {}
}

2.4 最终(后置)通知

  当目标方法执行后执行该方法体,不论是正常返回还是异常退出。其使用@After 注解来声明,最终通知必须准备处理正常返回和异常返回两种情况,通常用它来释放资源。

@Aspect
@Component
public class WebLogAspect {@Afterpublic void doAfter(JoinPoint joinPoint) {}
}

2.5 环绕通知

  环绕通知在一个方法执行之前和之后执行,它使得通知有机会在一个方法执行之前和执行之后运行。而且它可以决定标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。环绕通知使用@Around注解来声明。通知的第一个参数必须是 ProceedingJoinPoint类型。在通知体内,调用 ProceedingJoinPointproceed()方法会导致 后台的连接点方法执行。proceed 方法也可能会被调用并且传入一个 Object[]对象-该数组中的值将被作为方法执行时的参数。

@Aspect
@Component
public class WebLogAspect {@Aroundpublic Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {Object result = joinPoint.proceed();return result;}
}

三、附录

3.1 基于注解的切面类

package org.dllwh.service;public interface CustomerService {public void save(String name);public void update();
}

实现类要记得添加@Service,让该类作为Spring的IOC容器对象。

package org.dllwh.service.impl;import org.springframework.stereotype.Service;
import org.dllwh.service.CustomerService;@Service
public class CustomerServiceImpl implements CustomerService {@Overridepublic void save(String name) {System.out.println("执行save方法,name为:"+name);}@Overridepublic void update() {System.out.println("执行update方法");}
}

编写纯注解的切面类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class MyAspect {// 前置通知@Before(value = "execution(public * org.dllwh.service.impl.CustomerServiceImpl.*(..))")public void before() {System.out.println("前置通知");}// 最终通知@After(value = "execution(public * org.dllwh.service.impl.CustomerServiceImpl.*(..))")public void after(JoinPoint joinPoint) {System.out.println("最终通知");}// 后置通知@AfterReturning(value = "execution(public * org.dllwh.service.impl.CustomerServiceImpl.*(..))")public void afterReturning() {System.out.println("后置通知");}// 异常通知@AfterThrowing(value = "execution(public * org.dllwh.service.impl.CustomerServiceImpl.*(..))")public void afterThrowing() {System.out.println("异常通知");}// 环绕通知@Around(value = "execution(public * org.dllwh.service.impl.CustomerServiceImpl.*(..))")public void around(ProceedingJoinPoint pjp) {System.out.println("前置通知--前面代码");//执行目标对象方法try {pjp.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println("前置通知--后面代码");}}

编写纯注解的切面类

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configurable
@ComponentScan
@EnableAspectJAutoProxy  // 开启AOP注解功能
public class SpringConfig {}

小结

把今天最好的表现当作明天最新的起点…….~

  投身于天地这熔炉,一个人可以被毁灭,但绝不会被打败!一旦决定了心中所想,便绝无动摇。迈向光明之路,注定荆棘丛生,自己选择的路,即使再荒谬、再艰难,跪着也要走下去!放弃,曾令人想要逃离,但绝境重生方为宿命。若结果并非所愿,那就在尘埃落定前奋力一搏!

在这里插入图片描述

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

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

相关文章

Python数据分析实验二:Python数据预处理

目录 一、实验目的与要求二、实验任务三、主要程序清单和运行结果(一)对chipotle.csv文件的销售数据进行分析(二)对描述泰坦尼克号成员的信息进行可视化和相关分析 四、实验体会 一、实验目的与要求 1、目的:   掌握…

linux kernel内存泄漏检测工具之slub debug

一、背景 slub debug 是一个debug集,聚焦于kmem_cache 分配机制的slub内存(比如kmalloc),这部分内存在内核中使用最频繁,slub debug其中有相当部分是用来处理内存踩踏,内存use after free 等异常的&#x…

创建electron,解决包清理的问题,解决镜像源卡住下载时间长

我的电脑用户名是Anyphasy,我的node.js安装在D:\developp\nodejss18.18.0 使用npm config get prefix查看node.js安装路径 npm config get prefix 创建electron 创建package.json文件,它里面记载了你的electron版本,项目描述,以及启动命令等信息 npm init -y 先查看你自己的…

禅道项目管理系统身份认证绕过漏洞

禅道项目管理系统身份认证绕过漏洞 1.漏洞描述 禅道项目管理软件是国产的开源项目管理软件,专注研发项目管理,内置需求管理、任务管理、bug管理、缺陷管理、用例管理、计划发布等功能,完整覆盖了研发项目管理的核心流程。 禅道项目管理系统…

手写一个RNN前向传播以及反向传播

前向传播 根据公式 st tanh (Uxt Wst-1 ba) ot softmax(Vst by ) m 3 词的个数 n 5 import numpy as np import tensorflow as tf # 单个cell 的前向传播过程 # 两个输入,x_t,s_prev,parameters def rnn_cell_forward(x_t,s_prev,parameter…

运算符重载(1)

1.加号运算符重载&#xff0c;这里用编译器统一的名称operator代替函数名 #include<iostream> using namespace std; //1.成员函数的加号重载 //2.全局函数的加号重载 class Person { public:Person() {};//1.成员函数的加号重载//Person operator(Person& p)//{// P…

前端HTML5学习2(新增多媒体标签,H5的兼容性处理)

前端HTML5学习2新增多媒体标签&#xff0c;H5的兼容性处理&#xff09; 分清标签和属性新增多媒体标签新增视频标签新增音频标签新增全局属性 H5的兼容性处理 分清标签和属性 标签&#xff08;HTML元素&#xff09;和属性&#xff0c;标签定义了内容的类型或结构&#xff0c;而…

k8s学习(三十七)centos下离线部署kubernetes1.30(高可用)

文章目录 准备工作1、升级操作系统内核1.1、查看操作系统和内核版本1.2、下载内核离线升级包1.3、升级内核1.4、确认内核版本 2、修改主机名/hosts文件2.1、修改主机名2.2、修改hosts文件 3、关闭防火墙4、关闭SELINUX配置5、时间同步5.1、下载NTP5.2、卸载5.3、安装5.4、配置5…

BPE、Wordpiece、Unigram、SpanBERT等Tokenizer细节总结

BPE(Byte Pair Encoding) GPT-2和Roberta用的是这种&#xff0c;不会产生[UNK]这个unknown字符 这部分部分摘录自https://martinlwx.github.io/zh-cn/the-bpe-tokenizer/ 看以下code例子就足够理解了&#xff0c;核心是维护self.merges&#xff08;维护一个pair->str的字…

[蓝桥杯2024]-Reverse:rc4解析(对称密码rc4)

无壳 查看ida 这里应该运行就可以得flag&#xff0c;但是这个程序不能直接点击运行 按照伪代码写exp 完整exp&#xff1a; keylist(gamelab) content[0xB6,0x42,0xB7,0xFC,0xF0,0xA2,0x5E,0xA9,0x3D,0x29,0x36,0x1F,0x54,0x29,0x72,0xA8, 0x63,0x32,0xF2,0x44,0x8B,0x85,0x…

如何在 Visual Studio 中通过 NuGet 添加包

在安装之前要先确定Nuget的包源是否有问题。 Visual Studio中怎样更改Nuget程序包源-CSDN博客 1.图形界面安装 打开您的项目&#xff0c;并在解决方案资源管理器中选择您的项目。单击“项目”菜单&#xff0c;然后选择“管理 NuGet 程序包”选项。在“NuGet 包管理器”窗口中…

详解如何品味品深茶的精髓

在众多的茶品牌中&#xff0c;品深茶以其独特的韵味和深厚的文化底蕴&#xff0c;赢得了众多茶友的喜爱。今天&#xff0c;让我们一同探寻品深茶的精髓&#xff0c;品味其独特的魅力。 品深茶&#xff0c;源自中国传统茶文化的精髓&#xff0c;承载着世代茶人的智慧与匠心。这…

03-MVC执行流程-参数解析与Model

重要组件 准备Model&#xff0c;Controller Configuration public class WebConfig {ControllerAdvicestatic class MyControllerAdvice {ModelAttribute("b")public String bar() {return "bar";}}Controllerstatic class Controller1 {ResponseStatus(H…

windows环境下安装Apache

首先apache官网下载地址&#xff1a;http://www.apachelounge.com/download/按照自己的电脑操作系统来安装 这里我安装的是win64 主版本是2.4的apache。 然后解压压缩包到一个全英文的路径下&#xff01;&#xff01;&#xff01;一定一定不要有中文 中文符号也不要有&#xff…

ansible-copy用法

目录 概述实践不带目录拷贝带目录拷贝 概述 ansible copy 常用用法举例 不带目录拷贝&#xff0c;拷贝的地址要写全 带目录拷贝&#xff0c;拷贝路径不要写在 dest 路径中 实践 不带目录拷贝 # with_fileglob 是 Ansible 中的一个循环关键字&#xff0c;用于处理文件通配符匹…

【Vue3+Tres 三维开发】02-Debug

预览 介绍 Debug 这里主要是讲在三维中的调试,同以前threejs中使用的lil-gui类似,TRESJS也提供了一套可视化参数调试的插件。使用方式和之前的组件相似。 使用 通过导入useTweakPane 即可 import { useTweakPane, OrbitControls } from "@tresjs/cientos"const {…

数字文旅重塑旅游发展新格局:以数字化转型为突破口,提升旅游服务的智能化水平,为游客带来全新的旅游体验

随着信息技术的迅猛发展&#xff0c;数字化已成为推动各行各业创新发展的重要力量。在旅游业领域&#xff0c;数字文旅的兴起正以其强大的驱动力&#xff0c;重塑旅游发展的新格局。数字文旅以数字化转型为突破口&#xff0c;通过提升旅游服务的智能化水平&#xff0c;为游客带…

HarmonyOS Next从入门到精通实战精品课

第一阶段&#xff1a;HarmonyOS Next星河版从入门到精通该阶段由HarmonyOS Next星河版本出发&#xff0c;介绍HarmonyOS Next版本应用开发基础概念&#xff0c;辅助学员快速上手新版本开发范式&#xff0c;共计42课时 第一天鸿蒙NEXT Mac版、Windows版【编辑器】和【模拟器】&a…

BootStrap详解

Bootstrap简介 什么是BootStrap&#xff1f; BootStrap来自Twitter&#xff0c;是目前最受欢迎的响应式前端框Bootstrap是基于HTML、CSS、JavaScript的&#xff0c;它简洁灵活&#xff0c;使得Web开发更加快捷 为什么使用Bootstrap&#xff1f; 移动设备优先&#xff1a;自…

Kafka 3.x.x 入门到精通(07)——Java应用场景——SpringBoot集成

Kafka 3.x.x 入门到精通&#xff08;07&#xff09;——Java应用场景——SpringBoot集成 4. Java应用场景——SpringBoot集成4.1 创建SpringBoot项目4.1.1 创建SpringBoot项目4.1.2 修改pom.xml文件4.1.3 在resources中增加application.yml文件 4.2 编写功能代码4.2.1 创建配置…