AOP动态切点实现解耦提高代码复用性

Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的技术。它通过将横切关注点(例如日志记录、事务管理、安全性检查等)从主业务逻辑代码中分离出来,以模块化的方式实现对这些关注点的管理和重用。在Spring AOP中,切面(Aspect)是一个模块化的关注点,它可以跨越多个对象,例如日志记录、事务管理等。切面通过定义切点(Pointcut)和增强(Advice)来介入目标对象的方法执行过程。切点是一个表达式,用于匹配目标对象的一组方法,在这些方法执行时切面会被触发。一般来说切点表达式是一个固定的文件坐标,如下

    // 第一种
    // 切入点表达式
    @Pointcut("execution(* com.example.manage.service.*.*(..))")
    public void Log() {
    }

    @Around("Log()")
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        .............// AOP代码
    }

    // 第二种
    // 切入点坐标直接写入
    @Around("execution(* com.example.manage.service.*.*(..))")
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        .............// AOP代码
    }
  1. 前置增强(Before Advice):在目标方法执行之前执行的逻辑。
  2. 后置增强(After Advice):在目标方法执行之后执行的逻辑,不管目标方法是否抛出异常。
  3. 返回增强(After Returning Advice):在目标方法正常返回时执行的逻辑。
  4. 异常增强(After Throwing Advice):在目标方法抛出异常时执行的逻辑。
  5. 环绕增强(Around Advice):在目标方法执行前后都可以执行的逻辑,它可以完全控制目标方法的执行。

上文所使用的是 @Around,在目标方法执行前执行AOP业务逻辑,等目标方法执行完成后,在执行一段AOP业务逻辑,中间通过Object result = joinPoint.proceed();进行业务上下文分割 

    // 目标方法执行前业务逻辑
    // 如目标方法执行总耗时长
    Long begin = System.currentTimeMillis();
    
    // 目标方法开始执行
    Object result = joinPoint.proceed();
    
    // 目标方法执行后业务逻辑
    Long end = System.currentTimeMillis();
    Long costTime = end - begin;
    
    // 并且在AOP业务执行完后一定要返回目标方法的执行结果
    return result;

如果想要实现更加解耦提高代码复用性的AOP业务代码,则需要对切点进行优化,目前的切点表达式只能是固定某个方法层面,并不能刻意的去针对某一方法进行AOP,以下是动态切点思路

1、我们先自定义一个注解接口MyLog,需要使用@interface关键词,以及其上面的两个注解

@Retention(RetentionPolicy.RUNTIME)// 运行时生效
@Target(ElementType.METHOD)// 作用在哪些地方生效--方法上

@Retention(RetentionPolicy.RUNTIME)// 运行时生效
@Target(ElementType.METHOD)// 作用在哪些地方生效--方法上
public @interface MyLog {
}

2、在切入点表达式中直接将自定义接口MyLog坐标写入

    // 切入点坐标直接写入
    @Around("@annotation(com.example.aop.MyLog)")
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        .............// AOP代码
    }

3、直接在需要执行AOP业务逻辑的方法上添加注解@MyLog即可实现动态切点的AOP业务

    // 如删除功能需要执行AOP业务
    @MyLog
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) throws Exception {
        log.info("根据id删除部门:{}",id);

        deptService.delete(id);

        return Result.success();
    }

主要是由于有自定义注解MyLog中的@Target(ElementType.METHOD)注解实现获取当前方法的执行坐标,从而实现低耦合,执行相同AOP业务时比较简单,只需在目标方法加上自定义注解即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值