基于Spring AOP实现异常日志记录


一、前言

1. AOP简介

AOP (Aspect Orient Programming)面向切面编程,是Spring的两大核心功能之一,另一个是IOC(控制反转)。AOP的思想是将项目中重复的代码抽取来,使用动态代理技术,对已有的方法进行增强,常见的使用场景有:日志记录、事务处理、权限验证、性能检测。

2.关于代理

关于代理:SpringAOP是基于动态代理实现的,如果要代理的类实现了某个接口,那么AOP会使用JDK动态代理去创建代理对象;如果要代理的类没有实现接口,那么AOP会使用CGLib动态代理去生成一个被代理对象的子类作为代理。

二、开发步骤

1.引入依赖

在pom.xml中引入SpringAOP的依赖包

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

2.创建切面类

两个关键注解:
@Aspect:用于实现SpringAOP,标注该类为切面类。
@RestController:用于拦截controller的接口,当controller接口中抛出异常时,会被拦截,并返回错误信息。

代码如下:

@Aspect
@RestControllerAdvice
public class ExceptionLogAspect {
}

3.设置切点

设置异常日志切入点,指定哪些连接点要被拦截,异常日志一般扫描controller下的包。

代码如下:

    @Pointcut("execution(* com.lyc.controller..*.*(..))")
    public void exceptionLogPointCut(){}

4.通知方法

指拦截到连接点之后要做的事,即对切入点增强的内容,增强内容依照具体业务而定。
常见的通知方式有五种:
@Before:前置通知
@After:后置通知
@AfterReturning:返回后通知
@AfterThtowing:抛出异常后通知
@Around:环绕通知

异常日志记录的增强方法中,从连接点中获取各种异常信息,封装到异常日志对象中,最后存入数据库。
存入数据库有两种方式:
1.采用单线程方式,即直接调用插入数据库的业务进行保存。
2.开启异步任务,创建一个新线程,调用相应业务进行保存,多线程并发操作提高了系统的性能。

     /**
     * 异常通知,指定通知类型为AfterThrowing
     * @param joinPoint 封装了切面方法的信息
     * @param e 异常
     */
    @AfterThrowing(pointcut = "exceptionLogPointCut()",throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint,Throwable e){
        //获取目标方法中的一些信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取切入点所在的方法
        Method method = signature.getMethod();
        // 获取request
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
        // 获取操作
        Api api = (Api) signature.getDeclaringType().getAnnotation(Api.class);
        ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
        // 封装异常日志对象
        ExceptionLog exceptionLog = new ExceptionLog();
        // 异常模块
        exceptionLog.setModule(api.tags()[0]);
        // 请求URI
        exceptionLog.setUri(request.getRequestURI());
        // 异常名称
        exceptionLog.setName(e.getClass().getName());
        // 操作描述
        exceptionLog.setDescription(apiOperation.value());
        // 获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        // 获取请求的方法名
        String methodName = method.getName();
        methodName = className + "." + methodName;
        // 异常方法名称
        exceptionLog.setErrorMethod(methodName);

        // 请求方式
        exceptionLog.setRequestMethod(Objects.requireNonNull(request).getMethod());

        // 开启一个新线程,将数据保存到数据库
        AsyncManager.getInstance().execute(AsyncFactory.recordException(exceptionLog));
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring AOP(面向切面编程)是Spring框架中的一个重要模块,它提供了一种在程序运行期间动态地将额外的行为织入到代码中的方式。通过使用Spring AOP,我们可以将与业务逻辑无关的横切关注点(如日志记录、性能统计、事务管理等)从业务逻辑中分离出来,使得代码更加清晰、可维护和可扩展。 Spring AOP实现主要依赖于以下几个核心概念: 1. 切面(Aspect):切面是一个模块化的单元,它封装了与横切关注点相关的行为。在Spring AOP中,切面可以包含通知(Advice)和切点(Pointcut)。 2. 通知(Advice):通知定义了在切面的特定位置执行的代码。在Spring AOP中,有以下几种类型的通知: - 前置通知(Before):在目标方法执行之前执行。 - 后置通知(After):在目标方法执行之后执行,无论是否发生异常。 - 返回通知(After-returning):在目标方法正常返回之后执行。 - 异常通知(After-throwing):在目标方法抛出异常后执行。 - 环绕通知(Around):包围目标方法的执行,在前后都可以添加额外的逻辑。 3. 切点(Pointcut):切点定义了在哪些连接点(Joinpoint)上应用通知。通过使用切点表达式,我们可以指定需要拦截的方法或类。 4. 连接点(Joinpoint):连接点是在应用程序执行过程中能够插入切面的点,如方法调用、异常抛出等。 5. 织入(Weaving):织入是将切面应用到目标对象并创建代理对象的过程。Spring AOP支持编译时织入、类加载时织入和运行时织入三种方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值