Spring AOP(概念,使用)

目录

  • [Spring AOP](#Spring AOP)

Spring AOP

AOP是什么

  • Aspect Oriented Programminig(面向切面编程)
  • 切面 指的是某一类特定问题,比如说登录拦截器,就是对"登录校验",这一类问题的统一处理
  • 所以,拦截器是AOP的一种应用
  • AOP是一种思想,是对某一类事情的集中处理

什么是Spring AOP

  • AOP是一种思想,它的实现方法有很多,有Spring AOP,也有AspectJ ,CGLIB等。


AOP可以做到在不改动这些原始方法的基础上,针对特定的方法进行功能的增强

AOP的作用:在程序运行期间在不修改源代码的基础上,对已有的方法进行增强(无侵入性:解耦)

AOP实际开发流程

1. 引入依赖

在pom.xml文件中添加配置

xml 复制代码
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 编写AOP程序

业务:记录Controller中每个方法的执行时间

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class TimeAspect {
 /**
 * 记录⽅法耗时
 */
 @Around("execution(* com.example.demo.controller.*.*(..))")
 	public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
 //记录⽅法执⾏开始时间
 		long begin = System.currentTimeMillis();
 //执⾏原始⽅法
		 Object result = pjp.proceed();
 //记录⽅法执⾏结束时间
 		long end = System.currentTimeMillis();
 //记录⽅法执⾏耗时
		 log.info(pjp.getSignature() + "执⾏耗时: {}ms", end - begin);
 return result;
 }
}

Spring AOP详解

  1. @Aspect: 标识这是一个切面类
  2. @Around:环绕通知,在目标方法执行前后都会被执行。
  3. ProceedingJoinPoint.proceed() 让原始方法执行

Spring AOP中的核心概念

  1. 切点(Pointcut)
    提供一组规则,告诉程序对哪些方法来进行增强
  1. 连接点

    满足切点表达式规则的方法
    例如

    切点表达式:英雄联盟全部射手

    连接点:希维尔,艾希等各个射手

  2. 通知(Advice)

    具体要做的工作

  3. 切面(Aspect)

    切面 = 切点 + 通知
    切面所在的类,一般称为切面类

Spring AOP的通知类型

六种类型

上⾯我们讲了什么是通知, 接下来学习通知的类型. @Around 就是其中⼀种通知类型, 表⽰环绕通知.
Spring中AOP的通知类型有以下⼏种:
• @Around: 环绕通知, 此注解标注的通知⽅法在⽬标⽅法前, 后都被执⾏
• @Before: 前置通知, 此注解标注的通知⽅法在⽬标⽅法前被执⾏
• @After: 后置通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, ⽆论是否有异常都会执⾏
• @AfterReturning: 返回后通知, 此注解标注的通知⽅法在⽬标⽅法后被执⾏, 有异常不会执⾏
• @AfterThrowing: 异常后通知, 此注解标注的通知⽅法发⽣异常后执⾏

程序发生异常的情况下:

  1. @AfterReturning 标识的通知方法不会执行,@AfterThrowing 标识的通知方法执行
  2. @Around环绕通知中原始方法调用时有异常,通知中的环绕后的代码逻辑也不会在执行了

注意事项

  1. 环绕通知⽅法的返回值, 必须指定为Object, 来接收原始⽅法的返回值, 否则原始⽅法执⾏完毕, 是获取不到返回值的.
  2. @Around 环绕通知需要调用ProceedingJoinPoint.proceed() 来让原始⽅法执⾏, 其他通知不需要考虑⽬标⽅法执⾏.
  3. 一个切面类可以用多个切点
@PointCut

上⾯代码存在⼀个问题, 就是存在⼤量重复的切点表达式 execution(* com.example.demo.controller.. (...)) , Spring提供了 @PointCut 注解, 把公共的切点表达式提取出来, 需要⽤到时引⽤该切⼊点表达式即可.

上述代码就可以修改为:

java 复制代码
@Aspect
@Component
public class AspectDemo {
 //定义切点(公共的切点表达式)
 @Pointcut("execution(* com.example.demo.controller.*.*(..))")
 private void pt(){}
 //前置通知
 @Before("pt()")
 public void doBefore() {
 //...代码省略
 }
 //后置通知
 @After("pt()")
 public void doAfter() {
 //...代码省略
 }
 //返回后通知
 @AfterReturning("pt()")
 public void doAfterReturning() {
 //...代码省略
 }
 //抛出异常后通知
 @AfterThrowing("pt()")
 public void doAfterThrowing() {
 //...代码省略
 }
 //添加环绕通知
 @Around("pt()")
 public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
 //...代码省略
 }
}
@Order(切面优先级)

存在多个切⾯类时, 默认按照切⾯类的类名字⺟排序:

• @Before 通知:字⺟排名靠前的先执⾏

• @After 通知:字⺟排名靠前的后执⾏

但这种⽅式不⽅便管理, 我们的类名更多还是具备⼀定含义的.

Spring 给我们提供了⼀个新的注解, 来控制这些切⾯通知的执⾏顺序: @Order

该注解标识的切⾯类, 执⾏顺序如下:

• @Before 通知:数字越⼩先执⾏

• @After 通知:数字越⼤先执⾏

相关推荐
StayInLove7 分钟前
G1垃圾回收器日志详解
java·开发语言
对许11 分钟前
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“
java·log4j
鹿屿二向箔12 分钟前
基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
spring·mvc·mybatis
无尽的大道15 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
小鑫记得努力24 分钟前
Java类和对象(下篇)
java
binishuaio28 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE30 分钟前
【Java SE】StringBuffer
java·开发语言
老友@30 分钟前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
Upaaui1 小时前
Aop+自定义注解实现数据字典映射
java