自定义注解+AOP切面日志+源码

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 自定义注解+AOP切面日志+源码

注解

前言

注解是JavaEE的基础,更是在Spring中发扬光大。AOP中有大量使用。

说明

本案例主要通过俩个实操讲解、演示

  1. 切面注解日志
  2. 切面注解锁
  3. 切面注解权限

后俩个分别再出一个Demo,源码全部都在gitee免费提供

代码讲解

切面注解日志

1. 新建接口

新建接口用于测试

com\javapub\demo\annotation\springbootannotation\controller
2. 引入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
3. 注解
package com.javapub.demo.annotation.springbootannotation.annotation;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/ https://gitee.com/rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/25 15:22
 * @Version: 1.0
 * @Description: #自定义日志注解。
 * <p>
 * ①:什么时候使用该注解,我们定义为运行时;
 * ②:注解用于什么地方,我们定义为作用于方法上;
 * ③:注解是否将包含在 JavaDoc 中;
 * ④:注解名为 Log;
 * ⑤:定义一个属性,默认为空字符串;
 */

import java.lang.annotation.*;


@Target(ElementType.METHOD) //注解用于什么地方,我们定义为作用于方法上;
@Retention(RetentionPolicy.RUNTIME) //什么时候使用该注解,我们定义为运行时;
@Documented //注解是否将包含在 JavaDoc 中;
public @interface Log {//注解名为Log

    String value() default ""; //定义一个属性,默认为空字符串;

}
4. AOP切点类
  1. 这里实现了对自定义注解的环绕增强切点,对使用了自定义注解的方法进行AOP切面处理;
  2. 对方法运行时间进行监控;
  3. 对方法名,参数名,参数值,对日志描述的优化处理;

在方法上增加 @Aspect 注解声明切面,使用 @Pointcut 注解定义切点,标记方法。

使用切点增强的时机注解:@Before (前置通知),@Around,@AfterReturning,@AfterThrowing,@After(后置通知)

package com.javapub.demo.annotation.springbootannotation.aop;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/ https://gitee.com/rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/25 15:42
 * @Version: 1.0
 * @Description: 注释式日志切面
 */

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Slf4j
@Aspect //@Aspect:声明该类为一个注解类
@Component
public class LogAspect {

    /**
     * @Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为切某个注解,也可以切某个 package 下的方法;
     * <p>
     * 此处的切点是注解的方式,也可以用包名的方式达到相同的效果
     * '@Pointcut("execution(* com.javapub.demo.annotation.springbootannotation.*.*(..))")'
     */
    @Pointcut("@annotation(com.javapub.demo.annotation.springbootannotation.annotation.Log)")
    public void logPointCut() {
    }

    /**
     * @param joinPoint
     * @return
     * @throws Throwable
     * @Around 环绕,可以在切入点前后织入代码,并且可以自由的控制何时执行切点;
     * @Description: 这里其实应该使用 try{}catch(){}finally{} 做容错,为了代码简洁易懂就不加了
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //异步保存日志
        saveLog(joinPoint, time);
        return result;
    }

    void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = signature.getName();
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        System.out.println("**************************");
        System.out.println(method);
        log.info("------------------------接口日志-----------------------" + "\n"
                + "类名称:" + className + "\n"
                + "方法名:" + methodName + "\n"
                + "执行时间:" + time + "毫秒");
        log.info("接口参数" + "\n" + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 在切点之前,织入相关代码;
     *
     * @param joinPoint
     */
    @Before("logPointCut()")
    public void doBeforeAdvice(JoinPoint joinPoint) {
        log.info("进入方法前执行.....");
    }

    /**
     * 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;
     *
     * @param ret
     */
    @AfterReturning(returning = "ret", pointcut = "logPointCut()")
    public void doAfterReturning(Object ret) {
        log.info("方法的返回值 : {}", ret);
    }

    /**
     * 用来处理当织入的代码抛出异常后的逻辑处理;
     */
    @AfterThrowing("logPointCut()")
    public void throwss(JoinPoint jp) {
        log.info("方法异常时执行.....");
    }


    /**
     * 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
     */
    @After("logPointCut()")
    public void after(JoinPoint jp) {
        log.info("方法最后执行.....");
    }
}

测试

http://127.0.0.1:9001/order/order-info?id=1


http://127.0.0.1:9001/order/order-info-2/1


源码仓库:https://gitee.com/rodert/SpringBoot-javapub

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
1
1
0
143
分享
相关文章
(工作经验)优雅实现接口权限校验控制:基于自定义注解、AOP与@ConditionalOnProperty配置开关的通用解决方案
(工作经验)优雅实现接口权限校验控制:基于自定义注解、AOP与@ConditionalOnProperty配置开关的通用解决方案
227 1
|
4月前
|
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——Spring Boot 中的 AOP 处理
本文详细讲解了Spring Boot中的AOP(面向切面编程)处理方法。首先介绍如何引入AOP依赖,通过添加`spring-boot-starter-aop`实现。接着阐述了如何定义和实现AOP切面,包括常用注解如`@Aspect`、`@Pointcut`、`@Before`、`@After`、`@AfterReturning`和`@AfterThrowing`的使用场景与示例代码。通过这些注解,可以分别在方法执行前、后、返回时或抛出异常时插入自定义逻辑,从而实现功能增强或日志记录等操作。最后总结了AOP在实际项目中的重要作用,并提供了课程源码下载链接供进一步学习。
185 0
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——什么是AOP
本文介绍了Spring Boot中的切面AOP处理。AOP(Aspect Oriented Programming)即面向切面编程,其核心思想是分离关注点。通过AOP,程序可以将与业务逻辑无关的代码(如日志记录、事务管理等)从主要逻辑中抽离,交由专门的“仆人”处理,从而让开发者专注于核心任务。这种机制实现了模块间的灵活组合,使程序结构更加可配置、可扩展。文中以生活化比喻生动阐释了AOP的工作原理及其优势。
91 0
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
316 8
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
868 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
135 1
|
9月前
|
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
209 2
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
216 0
Spring高手之路22——AOP切面类的封装与解析
面向切面编程(AOP)介绍--这是我见过最易理解的文章
这是我见过的最容易理解的文章,由浅入深介绍AOP面向切面编程,用科普版和专家版分别解说,有概念,有代码,有总结。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问