AOP(Aspect Oriented Programming):面向切面编程

利用AOP切面可以对业务进行无侵入增强,在不改变原有逻辑的基础上,在其前后进行处理

概念

  • 切面(Aspect):一般指被@Aspect修饰的类,某一具体功能的AOP逻辑
  • 连接点(JoinPoint):被切入点选中的方法
  • 切入点(Pointcut):选择对哪些方法进行增强
  • 通知(Advice):对目标方法的增强,有以下五种增强类型

    • 环绕通知(@Around):内部执行方法,可自定义在方法执行的前后操作
    • 前置通知(@Before):在方法执行前执行
    • 后置通知(@After):在方法执行后执行
    • 返回通知(@AfterReturning):在方法返回后执行
    • 异常通知(@AfterThrowing):在方法抛出异常执行

    对于不同的方法,使其生效的匹配方式有很多

    表达式类型功能
    execution()匹配方法,最全的一个
    args()匹配入参类型
    @args()匹配入参类型上的注解
    @annotation()匹配方法上的注解
    within()匹配类路径
    @within()匹配类上的注解
    this()匹配类路径,实际上AOP代理的类
    targer()匹配类路径,目标类
    @target()匹配类上的注解

实现

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

创建切入注解

ElementType.TYPE 声明这个注解可以在类上使用

ElementType.METHOD 声明这个注解可以在方法上使用

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Aop {
}

编写切面类

  • 通过@Aspect告诉spring容器这是一个切面类,同时使用@Component注解将其声明成spring容器的组件
  • 创建一个成员方法(不用有具体的实现),在上面添加上@Pointcat注解,声明这是个切入点方法,在这里我们就可以选择不同的匹配方式,我们这里使用的是@Aop注解的方式
  • 实现具体的增强方法,通过@After、@Before...,并且在其中引入切入点方法
@Aspect
@Component
public class ScheduledAop {
    @Pointcut("@annotation(com.webwss.scheduled.annotation.Aop)")
    public void authcat(){
 
    }
 
    @After("authcat()")
    public void print(JoinPoint joinPoint){
        System.out.println("catprint running");
    }
 
    @Before("authcat()")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println(name);
    }
 
    @Around("authcat()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("开始执行");
        Object proceed = joinPoint.proceed();
        System.out.println("执行结束");
    }
 
    @AfterThrowing(value = "authcat()",throwing = "e")
    public void execption(JoinPoint joinPoint,Exception e){
        System.out.println(joinPoint.getSignature().getName() + ".exception:" + e.getMessage());
    }
 
    @AfterReturning("authcat()")
    public void afterReturn(JoinPoint joinPoint){
        System.out.println(joinPoint.getSignature().getName() + "执行结束");
    }
}

使用AOP

在具体的业务方法上添加上我们自定义的@Aop注解,告诉aop从这里切入,这里我们自己抛出了个异常,用来测试@AfterException,异常的前置通知

@Component
public class MySchduled {
    private int count = 0;
 
    @Aop
    @Scheduled(cron = "0/3 * * * * ? ")
    public void print(){
        System.out.println("hello:" + count++);
        if(count == 3){
            throw new RuntimeException("hello");
        }
    }
}

开启AOP

我们需要在启动类或者配置类上添加@EnableAspectJAutoProxy,开启aop

@SpringBootApplication
@EnableAspectJAutoProxy
public class AuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class,args);
    }
}

AOP应用场景

  • 记录日志:通过在方法调用前后插入切面逻辑,可以方便地实现日志记录功能,例如在方法调用前记录方法名和参数,以及在方法调用后记录方法的返回值
  • 监控方法运行时间(监控性能):AOP可以用于监控方法的运行时间,从而找出性能瓶颈,提高系统的性能
  • 权限控制:通过在方法调用前插入切面逻辑,可以实现安全性检查功能,例如检查用户的权限,只允许有特定权限的用户访问某些方法
  • 性能统计和计数:AOP可以用于统计方法的执行时间、调用次数等信息,帮助定位系统瓶颈和优化点
最后修改:2025 年 04 月 27 日
如果觉得我的文章对你有用,请随意赞赏