AOP(面向切面编程)是对面向对象编程的一个补充,通常用于日志记录、事务处理、权限管理等。
一、技术要点
1、Advice(通知)包含了需要用于多个应用对象的横切行为,简单来说是定义了“什么时候”和“做什么”。通知有以下五种类型:
①、前置通知(@Before)在目标方法调用之前
②、后置通知(@After)在目标方法调用之后
③、环绕通知(@Around)在被通知的方法调用之前和调用之后执行的自定义方法
④、返回通知(@After Returning)在目标方法成功执行之后调用通知
⑤、异常通知(@After Throwing)在目标方法抛出异常之后调用通知
2、Join Point(连接点)是程序执行过程中能够应用通知的所有点。
3、Pointcut(切点) 定义了在那些地方可以切入,那些连接点可以得到通知;切点一定是连接点。
4、Aspect(切面)是切点和通知的结合,通知和切点共同定义了面的全部内容--什么时候、什么地方完成什么功能。
5、Introduction(引入)允许我们向现有的类中加入新方法和属性
6、Weaving(织入)是把切面应用到目标对象并创建新的代理对象的过程,分为编译期织入、类加载期织入和运行期织入。
二、整合使用
加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
随便创建一个需要处理的类
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lyy
* @Title:
* @description:
* @date 2022/9/26 14:13
*/
@RestController
@RequestMapping(value = "/filter")
public class FilterController {
@RequestMapping(value = "filterDemo")
@ResponseBody
public String filterDemo(){
return "hello world!";
}
}
定义一个切面
package com.example.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author lyy
* @Title:
* @description:
* @date 2022/9/26 17:45
*/
@Component
@Aspect
public class ControllerAop {
@Pointcut("execution(* com.example.demo.controller.*.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void before(JoinPoint joinPoint){
System.out.println("执行Before通知=======================");
Object[] args = joinPoint.getArgs();
if (args.length<=0){
System.out.println("没有参数");
}
}
@After("pointcut()")
public void after(JoinPoint joinPoint){
System.out.println("执行After通知=======================");
}
@Around("pointcut()")
public String dataAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceed = joinPoint.proceed();
String str = (String)proceed+"123";
return str;
}
}
执行结果
环绕通知对返回值进行了处理的结果
execution表示在方法执行的时候触发。以“”开头,表明方法返回值类型为任意类型。然后是全限定的类名和方法名,“”可以表示任意类和任意方法。对于方法参数列表,可以使用“…”表示参数为任意类型。如果需要多个表达式,可以使用“&&”、“||”和“!”完成与、或、非的操作。