Springboot使用AOP操作日志

Springboot使用AOP操作日志

有时候项目中会记到操作日志,使用aop来实现会提高效率。

导包

  • 首先导入aop的jar包
<!--spring切面aop依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 自定义注解
@Target(ElementType.METHOD)//该注解表示自定义注解可以在那些地方使用
@Retention(RetentionPolicy.RUNTIME)//自定义注解何时有效
@Inherited//表示一个类如果使用@Inherited注解标志的注解@MyAnno,该类的子类也会继承到这个注解
@Documented//可以生成文档
public @interface MyAnno {
    String value() default "";
}
  • 使用自定义注解
    在这里插入图片描述
  • 定义切面类
    每次执行标有自定义注解的方法时,会先到切面中执行point.proceed();然后去执行当前执行的方法;
    最后将操作日志保存到数据库;
@Component
@Aspect
public class MyAspect {

    public static final Logger logger = LoggerFactory.getLogger(MyAspect.class);

    @Autowired
    private LogServiceImpl logService;

    //com.canola.demo.aopinterface.MyAnno 指自定义注解的路径
    @Pointcut("@annotation(com.canola.demo.aopinterface.MyAnno))")
    public void picut() {
    }

    @Before(value = "picut()")
    public void before() {
        logger.info("前置通知");
    }

    @After(value = "picut()")
    public void after() {
        logger.info("后置通知");
    }

    //环绕通知 有了环绕通知,前置和后置可以不用
    @Around(value = "picut()")
    public void around(ProceedingJoinPoint point) {
        long beginTime = System.currentTimeMillis();

        try {
            //会执行用户当前访问的方法
            Object proceed = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        //执行方法的时间
        long time = System.currentTimeMillis() - beginTime;
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        MyAnno myAnno = method.getAnnotation(MyAnno.class);
        Log log = new Log();
        if (myAnno != null) {
            //注解上的描述
            log.setDescri(myAnno.value());
        }
        //获取类名
        String className = point.getTarget().getClass().getName();
        //获取方法名
        String methodName = signature.getName();
        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        //获取ip
        String ipAddr = IPUtils.getIpAddr(request);
        log.setIpAddress(ipAddr);
        log.setMethodLog(className + "." + methodName + "()");
        log.setRunTime(time);
        log.setCreateTime(new Date());
        logService.add(log);
        logger.info("环绕通知");
    }
}
  • 数据库记录
    在这里插入图片描述
<think>好的,我现在需要帮用户解答如何在Spring Boot中使用AOP实现日志管理的问题。用户还提到需要按照之前的系统级指令来组织回答,包括正确使用LaTeX格式、生成相关问题,以及引用提供的参考资料。 首先,我应该回忆一下Spring Boot中AOP的基本概念。AOP即面向切面编程,用于将横切关注点(如日志、事务管理)与业务逻辑分离。用户需要的是具体的示例教程,所以需要一步步的指导。 接下来,我需要确保回答结构清晰,分步骤说明。可能需要包括添加依赖、创建自定义注解、编写切面类等步骤。同时,要引用用户提供的两个引用内容,尤其是关于@Pointcut和AOP核心概念的部分。 然后,检查是否需要数学公式。在这个问题中,可能涉及不到数学表达式,但根据系统指令,如果有行内或独立公式,必须正确使用LaTeX。目前看起来可能不需要,但如果有性能分析部分,可能会有公式,比如计算时间复杂度,比如$O(n \log n)$之类的。不过用户的问题主要是实现示例,可能不需要,但需要注意。 然后,生成相关问题。用户的问题是关于日志管理的,所以相关问题可能包括AOP的其他应用、性能影响、自定义注解的高级用法,或者与拦截器的比较。 另外,需要确保回答中的代码正确,并且符合Spring Boot的实践。比如,使用@Aspect注解,配置切点表达式,处理环绕通知等。同时,引用用户提供的引用[1]中的@Pointcut示例,引用[2]中的AOP核心概念。 现在,整理步骤: 1. 添加AOP依赖:Spring Boot Starter AOP。 2. 创建自定义注解@Log,用于标记需要记录日志的方法。 3. 编写切面类,定义切点并使用通知(如@Around)来记录日志信息。 4. 在业务方法上使用@Log注解,测试日志输出。 在编写切面类时,需要详细说明各个部分的作用,比如@Pointcut的表达式,如何获取方法信息,记录请求参数、执行时间等。 需要确保代码示例正确,比如环绕通知中使用ProceedingJoinPoint,处理异常情况,使用日志工具如Slf4j。 最后,验证是否引用了提供的资料,比如在提到@Pointcut时引用[^1],在解释AOP作用时引用[^2]。 同时,按照要求,在回答最后生成相关问题,确保相关问题与主题相关,并且有助于用户进一步探索。 现在需要检查是否有遗漏的步骤,比如是否需要配置启用AOP,不过在Spring Boot中通常自动配置,但可能需要@EnableAspectJAutoProxy,但根据Spring Boot的版本,可能不需要显式启用。 总结下来,回答的结构应该是: - 简介AOP日志管理中的作用,引用资料。 - 分步骤实现,包括依赖、注解、切面类、使用示例。 - 代码块展示。 - 相关问题和引用。</think>在Spring Boot中使用AOP实现日志管理,可通过定义切面(Aspect)捕获目标方法的执行信息。以下是分步实现示例: --- ### 1. 添加AOP依赖 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` --- ### 2. 创建自定义注解 定义`@Log`注解标记需记录日志的方法: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { String value() default ""; } ``` --- ### 3. 编写切面类 ```java @Aspect @Component @Slf4j // 需引入Lombok依赖 public class LogAspect { // 定义切点为@Log注解标记的方法 @Pointcut("@annotation(com.example.demo.annotation.Log)") public void logPointCut() {} // 环绕通知记录日志 @Around("logPointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Log logAnnotation = method.getAnnotation(Log.class); long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); // 执行目标方法 long endTime = System.currentTimeMillis(); // 记录日志信息 log.info("方法描述: {}", logAnnotation.value()); log.info("请求参数: {}", Arrays.toString(joinPoint.getArgs())); log.info("执行耗时: {}ms", endTime - startTime); return result; } } ``` --- ### 4. 在业务方法中使用注解 ```java @Service public class UserService { @Log(value = "查询用户信息") public User getUserById(Long id) { // 模拟业务逻辑 return new User(id, "testUser"); } } ``` --- ### 关键说明 - **切面定义**:通过`@Pointcut`指定注解定位目标方法,实现关注点分离。 - **环绕通知**:使用`@Around`拦截方法执行,可获取参数、返回值及耗时。 - **日志输出**:结合Slf4j记录操作细节,便于后续审计。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值