当前位置: 首页 > article >正文

关于springboot中使用AOP方式记录日志的思路和灵感

目录

日志级别

切点和通知区别:

在项目中实现日志记录功能方法

日志持久化

AOP方式:

1. 添加AOP依赖

2. 创建日志切面

3. 配置application.properties或application.yml

4. 使用切面

5. 测试日志功能


日志级别

通过设置不同的日志级别来查看不同程度的问题信息:

切点和通知区别:

  • 切点(Pointcut):定义了哪些方法会被增强,即“在哪里”进行增强。
  • 通知(Advice):定义了在匹配到切点时应该执行的具体行为,即“做什么”。

在项目中实现日志记录功能方法

  1. 使用AOP来实现日志记录功能
  2. 使用lombok框架的

配置Spring AOP:确保Spring AOP自动代理开启。

spring:
  aop:
    auto: true #启动aop配置

如何设置根日志记录级别:(在yml文件中)

logging:
  level:
    root:error

也可以针对某个子目录设置日志级别:

logging:
  level:
    root:error
    com:
      lyp:
        controller:debug
日志持久化

在生产环境中,我们常常把日志信息保存下来。而将日志信息保存下来的过程就叫做日志持久化

logging:
  file:
    name: D:\\home\\log\\spring-1024.log

使用lombok简单记录日志

AOP方式:

使用AOP(面向切面编程)在Spring Boot项目中添加日志功能是一种非常灵活和强大的方法。以下是通过AOP添加日志功能的步骤:

1. 添加AOP依赖

首先,确保你的项目中包含了Spring AOP和AspectJ的依赖。对于Maven项目,可以在pom.xml中添加如下依赖:

<dependencies>
  <!-- Spring Boot AOP starter -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>

  <!-- AspectJ -->
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
  </dependency>
</dependencies>

2. 创建日志切面

创建一个使用@Aspect注解的类来定义日志切面,并在其中定义切点和通知。


import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.aspectj.lang.JoinPoint;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    // 定义切点,这里以所有包下的类的所有方法为例子
    @Pointcut("execution(* *..*(..))")
    public void loggable() {
    }

    // 前置通知:在方法执行前执行
    @Before("loggable()")
    public void beforeAdvice(JoinPoint joinPoint) {
        logger.info("Before method: " + joinPoint.getSignature().getName());
    }

    // 后置通知:在方法执行后执行
    @After("loggable()")
    public void afterAdvice(JoinPoint joinPoint) {
        logger.info("After method: " + joinPoint.getSignature().getName());
    }

    // 返回通知:在方法成功执行后执行
    @AfterReturning(pointcut = "loggable()", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        logger.info("After returning method: " + joinPoint.getSignature().getName() + ", returned: " + result);
    }

    // 异常通知:在方法抛出异常后执行
    @AfterThrowing(pointcut = "loggable()", throwing = "error")
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception error) {
        logger.error("Exception in method: " + joinPoint.getSignature().getName() + ", exception: " + error);
    }
}

3. 配置application.propertiesapplication.yml

确保你的日志配置是正确的,以便日志可以被正确记录。

# application.properties
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG

4. 使用切面

一旦切面类被Spring容器管理,并且切点表达式匹配到相应的方法,AOP框架就会自动执行定义在切面类中的通知。

5. 测试日志功能

运行你的Spring Boot应用并调用一些方法,检查日志输出是否符合预期。

通过以上步骤,你可以在Spring Boot项目中使用AOP来添加日志功能。这种方式的好处是可以集中管理日志逻辑,减少业务代码的复杂性,并且可以灵活地调整日志级别和输出格式。

@Order(6)
@Aspect
@Component
@Slf4j
public class BcocServiceLogAspect {

    Logger logger = org.slf4j.LoggerFactory.getLogger(BcocServiceLogAspect.class);

    @Pointcut("execution(public * com.ztesoft.local.project.openservice.bcoc.*.*(..))")
    public void callIntfTimes(){
        logger.info("callIntfTimes 开始执行了...");
    }
    //统计请求的处理时间
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Before("callIntfTimes()")
    public void doBefore(JoinPoint joinPoint) throws Throwable{
        long time = System.currentTimeMillis() ;
        startTime.set(time);
        //接收到请求,记录请求内容
        //记录请求的内容
        logger.info("doBefore: time的值为:"+time);
    }

    @AfterReturning(returning = "ret" , pointcut = "callIntfTimes()")
    public void doAfterReturning(Object ret){
        //处理完请求后,返回内容
        logger.info("方法返回值:"+ JSON.toJSONString(ret) +",方法执行时间:"+ (System.currentTimeMillis() - startTime.get()));
        startTime.remove();
    }

}

java中日志类上面添加@order(6)注解,是什么意思、

        在Java中,@Order 注解通常与Spring框架中的组件扫描和依赖注入相关联。@Order 注解用于指定一个组件的加载顺序。当Spring容器需要按特定顺序加载多个组件时,@Order 注解可以用来定义这些组件的加载顺序。

        具体来说,@Order 注解接受一个整数值作为参数,该值越小,表示该组件越早被加载。这在处理多个组件需要按照特定顺序执行时非常有用,比如在Spring的拦截器(Interceptors)或过滤器(Filters)中。

对于日志类来说,如果上面添加了@Order(6)注解,这意味着:

  1. 这个日志类可能是一个Spring组件,比如一个拦截器或一个切面(Aspect)。
  2. 当Spring容器启动时,它会按照@Order注解指定的顺序来初始化和加载所有的组件。
  3. 这个日志类的加载顺序是6,意味着在所有使用@Order注解的组件中,它会在那些注解值为6或更小的组件之后加载,而在那些注解值为7或更大的组件之前加载。

如果没有特别指定@Order注解的值,Spring会使用默认的顺序值(通常是Ordered.LOWEST_PRECEDENCE),这通常意味着这些组件会在所有明确指定了顺序值的组件之后加载。

请注意,@Order注解是Spring框架特有的,如果你的日志类不是Spring管理的Bean,那么这个注解不会有任何效果。

为什么需要使用Order?

在Spring框架中使用@Order注解的原因通常与组件的加载和执行顺序有关。以下是一些使用@Order注解的主要场景和原因:

  1. 拦截器(Interceptors)顺序
    • 在Spring MVC中,拦截器用于在请求的生命周期中的特定点执行任务,比如在请求处理之前或之后。通过@Order注解,可以控制拦截器的执行顺序,这对于确保请求处理的正确性和一致性至关重要。
  1. 过滤器(Filters)顺序
    • 类似于拦截器,Servlet过滤器也需要按照特定的顺序执行。@Order注解可以帮助定义这些过滤器在请求处理链中的顺序。
  1. 切面(Aspects)顺序
    • 在使用Spring AOP(面向切面编程)时,不同的切面可能需要在不同的时机被触发。@Order注解可以用来指定切面的优先级,确保它们按照预期的顺序执行。
  1. 依赖注入顺序
    • 当有多个Bean需要注入同一个属性时,@Order注解可以决定这些Bean被注入的顺序。
  1. 事件监听器(EventListeners)顺序
    • 在处理事件时,不同的监听器可能需要按照特定的顺序执行。@Order注解可以用来控制这些监听器的执行顺序。
  1. 自定义组件顺序
    • 对于自定义的组件,比如自定义的Spring Boot自动配置类,可能需要控制它们被应用的顺序。
  1. 一致性和可预测性
    • 在复杂的应用程序中,不同的组件可能依赖于特定的执行顺序。使用@Order注解可以确保这种一致性和可预测性,避免因顺序不确定而导致的难以追踪的bug。
  1. 优化性能
    • 在某些情况下,按照特定的顺序执行组件可以提高应用程序的性能。
  1. 遵守业务规则
    • 业务逻辑可能要求某些操作必须在其他操作之前或之后执行,@Order注解可以帮助实现这些业务规则。

总的来说,@Order注解提供了一种灵活的方式来控制Spring容器中组件的加载和执行顺序,这对于维护大型、复杂的Spring应用程序的稳定性和可维护性是非常重要的。


http://www.kler.cn/a/408715.html

相关文章:

  • Python/GoLang/Java 多环境管理工具 pyenv/goenv/jenv
  • 16:(标准库)ADC三:使用外部触发启动ADC/模拟看门狗
  • CTF之密码学(Polybius密码)
  • 241124_基于MindSpore学习GPT2
  • C++ std::unique_ptr的使用及源码分析
  • 【Spring源码核心篇-03】精通spring的aop的底层原理和源码实现
  • c++(入门)
  • 群核科技首次公开“双核技术引擎”,发布多模态CAD大模型
  • 从零开始:使用 Spring Boot 开发图书管理系统
  • pip 与当前python环境版本不匹配, pyenv, pipenv, conda
  • 速盾:海外服务器使用CDN加速有什么优势?
  • [Python3学习笔记-基础语法] Python3 基础语法
  • Excel如何批量导入图片
  • UE5中T_noise 纹理的概述
  • 前端把dom页面转为pdf文件下载和弹窗预览
  • C语言蓝桥杯组题目
  • transformer.js(一):这个前端大模型运行框架的可运行环境、使用方式、代码示例以及适合与不适合的场景
  • C#里怎么样使用多线程读取多文件?
  • 深度学习实战图像缺陷修复
  • 二分查找的几种寻找情况