关于AOP的介绍和使用

一、AOP的概念

AOP是一种面向切面编程的范式,AOP通过动态代理的方式实现对方法的拦截和处理。在运行时,AOP框架会自动生成代理对象,将切面逻辑织入到目标对象的方法中,实现对方法的增强和修改。通过将横切关注点从主要业务逻辑中分离出来,提高了代码的可读性、可维护性和可重用性。它通过切面和连接点的概念来实现,可以用于解决许多常见的横切关注点问题。

二、AOP的使用场景

AOP可以在许多不同的场景中使用,以下是一些常见的使用场景:

  1. 日志记录:通过在方法调用前后插入切面逻辑,可以方便地实现日志记录功能。例如,可以在方法调用前记录方法名和参数,以及在方法调用后记录方法的返回值。

  2. 事务管理:AOP可以用于实现事务管理功能,例如在方法调用前开启事务,在方法调用后提交事务或回滚事务。这样可以简化事务管理的代码,提高代码的可读性和可维护性。

  3. 安全性检查:通过在方法调用前插入切面逻辑,可以实现安全性检查功能。例如,可以检查用户的权限,只允许有特定权限的用户访问某些方法。

  4. 性能监控:AOP可以用于实现性能监控功能,例如在方法调用前记录方法的开始时间,在方法调用后记录方法的结束时间,并计算方法的执行时间。这样可以方便地监控方法的性能,找出性能瓶颈。

  5. 异常处理:AOP可以用于实现异常处理功能,例如在方法调用后捕获异常并进行处理。这样可以统一处理异常,避免在每个方法中都进行异常处理的重复代码。

  6. 缓存管理:AOP可以用于实现缓存管理功能,例如在方法调用前检查缓存中是否存在结果,在方法调用后将结果存入缓存。这样可以提高系统的性能,避免重复计算。

  7. 日志审计:AOP可以用于实现日志审计功能,例如在方法调用前记录用户的操作,包括操作的类型、时间和操作的对象等。这样可以方便地进行日志审计和追踪

三、AOP具体的实现

这里我们可以通过AOP自定义注解记录所有到controller中方法的运行日志,具体实现如以下代码:

1.这个注解的作用是用于在方法上添加日志描述信息。通过在方法上使用@LogAnno注解,并设置methodDesc成员变量的值,我们可以在运行时获取该注解,并获取方法的描述信息。这样可以方便地在日志记录中使用该描述信息,提高日志的可读性和可维护性。

package com.itheima.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) //保留到运行阶段
@Target(ElementType.METHOD)  //只能加在方法上
public @interface LogAnno {
    String methodDesc() default "";
}

2.这段代码是一个使用AOP的切面类,作用是实现对标注了LogAnno注解的方法进行操作日志记录。具体来说,它通过AOP的方式,在这些方法执行前后添加额外的逻辑,实现对方法的拦截和处理。


@Aspect
@Component
public class LogAspect {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    //切点  标注LogAnno注解的方法都被切
    @Pointcut("@annotation(com.itheima.anno.LogAnno)")
    public void pt() {

    }

    //环绕通知
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        OperateLog operateLog = new OperateLog();
        // 获取类名
        operateLog.setClassName(pjp.getTarget().getClass().getName());
        //获取方法参数
        operateLog.setMethodParams(Arrays.toString(pjp.getArgs()));

        // org.aspectj.lang.reflect.MethodSignature
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        // 获取方法名
        operateLog.setMethodName(ms.getMethod().getName());
        LogAnno logAnno = ms.getMethod().getAnnotation(LogAnno.class);
        //获取方法描述
        operateLog.setMethodDesc(logAnno.methodDesc());
        String token = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(token);
        // 拿到用户id
        Integer id = claims.get("id", Integer.class);
        operateLog.setOperateUser(id);
        // 操作时间
        operateLog.setOperateTime(LocalDateTime.now());
        long begin = System.currentTimeMillis();
        Object obj = pjp.proceed();
        long end = System.currentTimeMillis();
        // 方法执行时间
        operateLog.setCostTime(end - begin);
        // 方法返回信息
        operateLog.setReturnValue(obj.toString());
        //落库
        operateLogMapper.insert(operateLog);
        return obj;
    }
}

总之,AOP(面向切面编程)是一种编程范式,它通过将横切关注点(如日志记录、事务管理等)从业务逻辑中剥离出来,以模块化的方式进行管理和复用。AOP通过在方法执行的前后插入额外的逻辑,实现对方法的拦截和处理。

你可能感兴趣的:(java,开发语言,spring,servlet)