学习Spring Boot:(二十二)使用 AOP

前言

AOP,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。基于AOP实现的功能不会破坏原来程序逻辑,因此它可以很好的对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

正文

Spring Boot 中使用

  1. pom.xml 中加入 aop 依赖:
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
  1. 当我们需要在非接口上面进行切面操作的时候,就需要 CGLIB来实现 AOP,在系统配置文件中加入设置:
spring: aop:proxy-target-class: true

默认为 false

切点表达式

列出常用的几个表达式:

  1. execution() 满足execution中描述的方法签名。 execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
    * modifier-pattern:表示方法的修饰符;
    * ret-type-pattern:表示方法的返回值
    * declaring-type-pattern:表示方法所在的类的路径
    * name-pattern:表示方法名
    * param-pattern:表示方法的参数
    * throws-pattern:表示方法抛出的异常
    * 其中后面跟着?的是可选项。

  2. this()是用来限定方法所属的类,为接口则限定所有的实现类,为类的话,限定这单个类。

  3. @annotation表示具有某个标注的方法。

  4. args 表示方法的参数属于一个特定的类,@args 表示参数有特定的标注注解。

  5. within 包或者类型满足within中描述的包或者类型的类的所有非私有方法,@within 类型拥有@target描述中给出的annotation,其中@target和@within的区别在于@within要求的annotation的级别为CLASS,而@target为RUNTIME
    . target 业务实例对象(非代理实例)的类型满足target 中的描述的类型,@target 类型拥有@target描述中给出的annotation

  6. bean() 表示所有匹配的 bean,例如 ,bean(“*Service”),匹配所有 Service 结尾的类。可以使用 !bean() 表示不匹配。

注意事项:
* 在各个pattern中,可以使用”*”来表示匹配所有。
* 在param-pattern中,可以指定具体的参数类型,多个参数间用,隔开,各个也可以用 * 来表示匹配任意类型的参数,如(String)表示匹配一个String参数的方法;(*,String)表示匹配有两个参数的方法,第一个参数可以是任意类型,而第二个参数是String类型。
* 可以用(..)表示零个或多个任意的方法参数。
* 使用&&符号表示与关系,使用||表示或关系、使用!表示非关系。在XML文件中使用andornot这三个符号。

AspectJ提供了五种定义通知的标注:

  • @Before:前置通知,在调用目标方法之前执行通知定义的任务
  • @After:后置通知,在目标方法执行结束后,无论执行结果如何都执行通知定义的任务
  • @AfterReturning:后置通知,在目标方法执行结束后,如果执行成功,则执行通知定义的任务
  • @AfterThrowing:异常通知,如果目标方法执行过程中抛出异常,则执行通知定义的任务
  • @Around:环绕通知,在目标方法执行前和执行后,都需要执行通知定义的任务

通过标注定义通知只需要两个步骤:

  1. 将以上五种标注之一添加到切面的方法中
  2. 在标注中设置切点的定义。

创建环绕通知

环绕通知相比其它四种通知有其特殊之处。环绕通知本质上是将前置通知、后置通知和异常通知整合成一个单独的通知。

@Around标注的方法,该方法必须有一个ProceedingJoinPoint类型的参数,

在方法体中,需要通过这个参数,以joinPoint.proceed();的形式调用目标方法。注意在环绕通知中必须进行该调用,否则目标方法本身的执行就会被跳过。

计算方法的执行时间:

    @Around("logPointCut()") //切点public Object around(ProceedingJoinPoint point) throws Throwable {long beginTime = System.currentTimeMillis();//执行方法Object result = point.proceed();//执行时长(毫秒)long time = System.currentTimeMillis() - beginTime;return result;}

处理通知中参数

获取参数的方式则需要使用关键词是args

    @Pointcut("bean(sysUserServiceImpl) && args(userEntity,..)")public void userPointCut(SysUserEntity userEntity) {}@Before("userPointCut(userEntity)")public void validateUser(SysUserEntity userEntity) {// to handler args}

这里有个非常严格的一点就是,args(userEntity,..),表示目标方法,可能有多个参数,但是包括 userEntity,这里 userEntity 必须参数名相同,不同就编织了。

args()中参数的名称必须跟切点方法的签名中public void validateUser(SysUserEntity userEntity)的参数名称相同。如果使用切点函数定义,其中的参数名称也必须与通知方法签名中的参数完全相同

AfterReturning增强处理

    @AfterReturning(pointcut = "logPointCut()", returning = "rtv")public void logAfter(Object rtv) {System.out.println(Objects.toString(rtv));}

使用 @AfterReturning 注解时,指定了一个returning属性,假设该属性值为rvt,这表明允许在Advice方法(logAfter()方法)中定义名为rvt的形参,程序可通过rvt形参来访问目标方法的返回值。

注意:
虽然AfterReturning增强处理可以访问到方法的返回值,但它不可以改变目标方法的返回值。

AOP切面的优先级

有时候,我们对一个方法会有多个切面的问题,这个时候还会涉及到切面的执行顺序的问题。

我们可以定义每个切面的优先级, Spring 中提供注解 @Order(i) ,当 i 的值越小,优先级越高。

参考文章

  • Spring AOP中定义切点(PointCut)和通知(Advice)
  • Spring Boot中使用AOP统一处理Web请求日志

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

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

相关文章

matlab怎么求hadamard,hadamard matlab

3、图像Hadamard变换 数字图像处理 ? Matlab没有提供图像Hadamard变换功能,不过 提供了求Hadamard变换矩阵的功能。例如使用 命令hadamard(8)能够得到下面[8 8]的......(A) 1.0000 命令 hadamard 矩阵 函数 hadamard 格式 H hadamard(n) 例 1-15 >> hhadamard(4) h 1 1…

学习Spring Boot:(二十三)Spring Boot 中使用 Docker

前言 简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建&#xff0c;发布一个镜像&#xff0c;现在我们通过远程的 docker api 构建镜像&#xff0c;运行容器&#xff0c;发布镜像等操作。 这里只介绍两种方式&#xff1a; 远程命令 api &#xff08;需要知道 Docker …

nginx php大文件上传,Nginx+PHP上传大文件设置

nginx的修改send_timeout 60;fastcgi_connect_timeout 300;fastcgi_send_timeout 300;fastcgi_read_timeout 300;client_max_body_size 30m; 可以全局设置也可以每个网站单独设置php的修改upload_max_filesize 10Mpost_max_size 15M 该项应该要大于 upload_max_filesizemax_inp…

学习Spring Boot:(二十四)多数据源配置与使用

前言 随着业务量增大&#xff0c;可能有些业务不是放在同一个数据库中&#xff0c;所以系统有需求使用多个数据库完成业务需求&#xff0c;我们需要配置多个数据源&#xff0c;从而进行操作不同数据库中数据。 正文 JdbcTemplate 多数据源 配置 需要在 Spring Boot 中配置…

matlab 超限像素平滑法,matlab超限像素平滑法_图像增强技术.ppt

主讲&#xff1a;苏菡 susuhansicnu.edu.cn 图象增强技术概述 目标&#xff1a;“视觉”效果更好&#xff0c;图象保真度不是首要目标 方法&#xff1a; 空间域增强&#xff1a;直接处理图象的象素 频率域增强&#xff1a;修改图象的傅立叶变换 评价&#xff1a;高度主观 视觉解…

学习Spring Boot:(二十五)使用 Redis 实现数据缓存

前言 由于 Ehcache 存在于单个 java 程序的进程中&#xff0c;无法满足多个程序分布式的情况&#xff0c;需要将多个服务器的缓存集中起来进行管理&#xff0c;需要一个缓存的寄存器&#xff0c;这里使用的是 Redis。 正文 当应用程序要去缓存中读取数据&#xff0c;但是缓存…

php ai库,收藏 | 深度学习框架、AI库、ML库、NLP库、CV库汇总!

一份包含深度学习框架、AI工具/库、机器学习工具/库、NLP工具/库、CV工具/库的汇总&#xff0c;并附有说明文档(有些是中英文文档都有)。之所以附带文档而不是源码&#xff0c;有两方面原因&#xff1a;先看文档&#xff0c;找出最适合自己的一个或两个(太多没必要&#xff0c;…

学习Spring Boot:(二十六)使用 RabbitMQ 消息队列

前言 前面学习了 RabbitMQ 基础&#xff0c;现在主要记录下学习 Spring Boot 整合 RabbitMQ &#xff0c;调用它的 API &#xff0c;以及中间使用的相关功能的记录。 相关的可以去[我的博客/RabbitMQ] 正文 我这里测试都是使用的是 topic 交换器&#xff0c;Spring Boot 2.…

appnode php,环境软件路径参考

[TOC]## Nginx* 主程序路径&#xff1a;/usr/sbin/nginx* 配置文件路径&#xff1a;/etc/nginx.conf* 服务控制命令&#xff1a;* CentOS 6&#xff1a;service nginx start|stop|reload|restart* CentOS 7&#xff1a;systemctl start|stop|reload|restart nginx.service## PH…

学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator

前言 主要是完成微服务的监控&#xff0c;完成监控治理。可以查看微服务间的数据处理和调用&#xff0c;当它们之间出现了异常&#xff0c;就可以快速定位到出现问题的地方。 springboot - version: 2.0 正文 依赖 maven 项目 在 pom.xml 文件中加入 actuator 的依赖&…

php实现注销功能,laravel 实现用户登录注销并限制功能

在项目根目录输入&#xff1a; php artisan make:controller Admin/LoginControllerphp artisan make:model Model/Admin -m运行之后 项目中会新增两个PHP文件新创建了admins用户表&#xff0c;此用户表默认新建中只有主键&#xff0c;创建时间&#xff0c;编辑时间。我们接下来…

将ipynb文件转为py的简单方法(图文并茂)

打开可以使用jupyter命令的命令窗口&#xff08;如果没有jupyter则需要先安装jupyter&#xff09;&#xff0c;cd 命令进入到 ipynb 文件所在的文件夹&#xff0c;执行 jupyter nbconvert --to script xxx.ipynb 即可完成 ipynb 文件到 py 文件的转化&#xff0c;执行 jupyter …

学习Spring Boot:(二十八)Spring Security 权限认证

前言 主要实现 Spring Security 的安全认证&#xff0c;结合 RESTful API 的风格&#xff0c;使用无状态的环境。 主要实现是通过请求的 URL &#xff0c;通过过滤器来做不同的授权策略操作&#xff0c;为该请求提供某个认证的方法&#xff0c;然后进行认证&#xff0c;授权成…

在PHP中如何要json中的数据,如何在不知道键值的情况下在php中读取JSON数据

我需要在php中读取firebase JSON URL然后显示它.我的firebase得到了以下.json数据&#xff1a;{"dDsdE4AlB7P5YYd4fWbYTQKCLPh1":{"email":"abhigmail.com","name":"abhishek"},"z1ceiLhdh9YVu7lGnVvqDWoWHFH3":{…

oracle 分区字符转换,Oracle 普通表与分区表转换

oracle 9i提供了dbms_redefinition包来实现数据库的表的在线重定义功能。在实际的应用上&#xff0c;我们可以利用这个包来进行&#xff1a;(1)堆表与分区之间进行转换。(2)重建表以减少HWM。10g能shrink&#xff0c;9i如果用move tablespace and rebuild index在move的时候会锁…

Java中使用有返回值的线程

在创建多线程程序的时候&#xff0c;我们常实现Runnable接口&#xff0c;Runnable没有返回值&#xff0c;要想获得返回值&#xff0c;Java5提供了一个新的接口Callable&#xff0c;可以获取线程中的返回值&#xff0c;但是获取线程的返回值的时候&#xff0c;需要注意&#xff…

Mybatis 插入时获取主键的方式

mybatis 作为一个主流的 ORM 框架&#xff0c;深受广大开发者的喜爱。有人的地方就有江湖&#xff0c;有代码的地方自然有坑&#xff0c;下面来说说获取 mybatis 的插入后返回的主键。 我们可以想一下自动增长的主键特性&#xff0c;在数据库里面肯定有某个地方管理 ID 的自增…

linux脚本怎么把文件地址变成动态地址,Linux脚本程序自动修改网卡配置文件中的MAC地址...

在玩Linux虚拟机的时候&#xff0c;一个安装好linux系统的virtual HDD会用于创建多个虚拟机&#xff0c;这样就不需要在创建每个虚拟机都安装一遍系统了。virtual HDD加载到虚拟机后&#xff0c;新的虚拟机的MAC地址就会和virtual系统中ifcfg-eth[0&#xff0d;9]中的MAC地址不…

MySQL + MyBatis 批量插入时存在则忽略或更新记录

一、存在时则忽略 为什么在发现重复时会忽略&#xff1f;这里面涉及到两个地方。 1、重复则忽略。那么首先是需要判断是否重复&#xff0c;这里是通过唯一索引判断是否重复的。如果表中唯一索引的字段已经存在与将要插入的记录行中唯一索引的字段值相同&#xff0c;则标识为重…

Linux 目录所属组设置,Linux系统用户与组管理命令及配置文件总结

一、Linux系统用户及组分类1、用户类别Linux系统中的用户大致可分为三类&#xff1a;root用户、系统用户、普通用户。每一个用户都拥有一个唯一的身份标识UID。2、组分类与用户信息对应的&#xff0c;Linux系统中的组也可分为三类&#xff1a;root组、系统组、普通组。每一个组…