SpringBoot自定义注解之实现AOP切面日志详解

通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP 切面统一打印出入参日志。

一、先看下项目结构

二、Maven JAR依赖

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

三、自定义注解

@SysLog

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SysLog {
 
    /**
     * 操作对象
     * **/
    String obj() default "";
 
    /**
     * 操作内容
     * **/
    String text() default "";
}

四、AOP切面

import java.lang.reflect.Method;
 
import com.zxk.demo.annotation.SysLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
 
 
@SuppressWarnings("all")
@Aspect
@Component
public class SysLogAspect {
 
    // 切入点
    @Pointcut(value = "@annotation(com.zxk.demo.annotation.SysLog)")
    private void pointcut() {
    }
 
    /**
     * 在方法执行前
     * @param point
     * @param myLog
     * @return
     */
    @Before(value = "pointcut() && @annotation(sysLog)")
    public void before(SysLog sysLog){
        System.out.println("++++执行了before方法++++");
    }
 
 
    /**
     * 在方法执行前后
     * @param point
     * @param myLog
     * @return
     */
    @Around(value = "pointcut() && @annotation(sysLog)")
    public Object around(ProceedingJoinPoint point, SysLog sysLog) {
        System.out.println("++++执行了around方法++++");
        String obj = sysLog.obj();
        String text = sysLog.text();
        // 拦截的类名
        Class clazz = point.getTarget().getClass();
        // 拦截的方法
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod;
        try {
            currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
            System.out.println("执行了类:" + clazz.getSimpleName());
            System.out.println("方法:" + currentMethod.getName());
            System.out.println("自定义注解:" + obj+"==="+text);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            return point.proceed(); // 执行程序
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return throwable.getMessage();
        }
    }
 
    /**
     * 方法执行后
     * @param joinPoint
     * @param myLog
     * @param result
     * @return
     */
    @AfterReturning(value = "pointcut() && @annotation(sysLog)", returning = "result")
    public Object afterReturning(JoinPoint joinPoint, SysLog sysLog, Object result) {
        // HttpServletRequest request = ((ServletRequestAttributes)
        // RequestContextHolder.getRequestAttributes()).getRequest();
        // HttpSession session = request.getSession();
        /**
         * 将信息保存到数据库
         * **/
        System.out.println("++++执行了afterReturning方法++++");
        System.out.println("自定义注解:" + sysLog.obj()+"=="+sysLog.text());
        System.out.println("执行结果:" + result);
        return result;
    }
 
    /**
     * 方法执行后 并抛出异常
     * @param joinPoint
     * @param myLog
     * @param ex
     */
    @AfterThrowing(value = "pointcut() && @annotation(sysLog)", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, SysLog sysLog, Exception ex) {
        System.out.println("++++执行了afterThrowing方法++++");
        System.out.println("请求:" + sysLog.text() + " 出现异常");
    }
}

五、Controller层实现

@SysLog(obj = "操作对象", text = "操作内容")
@GetMapping("/index")
    public String hello() {
//        int num = 5/0;
//        System.out.println("执行结果:" + num);
        return "hello word";
    }

六、测试

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅析Spring基于注解的AOP

    目录 一.准备工作 二.基于注解的AOP之前置通知 三.基于注解的AOP之切入点表达式的语法和重用以及获取连接点的信息 ①切入点表达式的语法 ②获取连接点的信息 ③重用写入点表达式 一.准备工作 ①创建一个Maven工程 ②添加依赖 在IOC所需依赖基础上再加入下面依赖即可: <!-- spring-aspects会帮我们传递过来aspectjweaver --> <dependency> <groupId>org.springframework</groupId

  • Spring Aop常见注解与执行顺序详解

    目录 Spring Aop 的常用注解 常见问题 示例代码 配置文件 接口类 实现类 aop 拦截器 测试类 执行结论 多切面的情况 代理失效场景 总结 Spring 一开始最强大的就是 IOC / AOP 两大核心功能,我们今天一起来学习一下 Spring AOP 常见注解和执行顺序. Spring Aop 的常用注解 首先我们一起来回顾一下 Spring Aop 中常用的几个注解: @Before 前置通知:目标方法之前执行 @After 后置通知:目标方法之后执行(始终执行) @After

  • SpringBoot通过AOP与注解实现入参校验详情

    目录 前言: 注解标记 通过AOP对方法进行增强 测试Get请求 测试POST请求 解决方法代码 再次测试POST请求 前言: 问题源头: 在日常的开发中,在Service层经常会用到对某一些必填参数进行是否存在的校验.比如我在写一个项目管理系统: 这种必填参数少一些还好,如果多一些的话光是if语句就要写一堆.像我这种有代码洁癖的人看着这一堆无用代码更是难受. 如何解决: 在Spring里面有一个非常好用的东西可以对方法进行增强,那就是AOP.AOP可以对方法进行增强,比如:我要校验参数是否存在

  • Spring AOP结合注解实现接口层操作日志记录

    目录 1.表和实体设计 1.实体设计 2.表结构设计 2.日志注解 3.核心AOP类 4.用到的工具类 5.测试类 6.测试结果 1.表和实体设计 1.实体设计 实体基类 @Data //映射将仅应用于其子类 @MappedSuperclass //指定要用于实体或映射超类的回调侦听器类.此注释可以应用于实体类或映射的超类. @EntityListeners(AuditingEntityListener.class) public class BaseEntity implements Seri

  • SpringBoot中利用AOP和拦截器实现自定义注解

    目录 前言 Spring实现自定义注解 1.引入相关依赖 2.相关类 Java实现自定义注解 通过Cglib实现 通过JDk动态代理实现 Cglib和JDK动态代理的区别 写在最后 前言 最近遇到了这样一个工作场景,需要写一批dubbo接口,再将dubbo接口注册到网关中,但是当dubbo接口异常的时候会给前端返回非常不友好的异常.所以就想要对异常进行统一捕获处理,但是对于这种service接口使用@ExceptionHandler注解进行异常捕获也是捕获不到的,应为他不是Controller的

  • Spring AOP如何在注解上使用SPEL表达式注入对象

    目录 在注解上使用SPEL表达式注入对象 场景描述 具体案例 补充 Spring属性注入方式之SPEL表达式 在注解上使用SPEL表达式注入对象 场景描述 在平时开发中,我们经常通过定义一些注解,进行轻量级开发. 今天主要研究的内容是关于如何在注解上通过spel表达式注入对象,以此调用注入对象的具体业务处理逻辑,然后在通过对表达式的解析,进而获取该业务逻辑处理的结果,类似于Spring Security中的@PreAuthorize, @PreAuthorize, @PostAuthorize等

  • Java SpringAOP技术之注解方式详解

    目录 1.配置xml扫描注解 2.配置注解 3.配置文件中开启自动代理 4.通知类型注解 5.测试类 6.结果 总结 1.配置xml扫描注解 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchem

  • SpringBoot自定义注解之实现AOP切面日志详解

    通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP 切面统一打印出入参日志. 一.先看下项目结构 二.Maven JAR依赖 <!-- AOP -->     <dependency>             <groupId>org.springframework.boot</groupId>             <

  • Springboot常用注解及配置文件加载顺序详解

    Springboot常用注解及底层实现 1.@SpringBootApplication:这个注解标识了一个SpringBoot工程,她实际上是另外三个注解的组合,分别是: @SpringBootConfiguration:源码可以看到,这个注解除了元注解外,实际就只有一个@Configuration,把该类变成一个配置类,表示启动类也是一个配置类: @EnableAutoConfiguration:是开启自动配置的功能,向Spring容器中导入了一个Selector,用来加载ClassPath

  • SpringBoot自定义MessageConverter与内容协商管理器contentNegotiationManager详解

    目录 1.自定义消息转换器MessageConverter 2.自定义内容协商管理器contentNegotiationManager 1.自定义消息转换器MessageConverter 在WebMvcAutoConfiguration类中有一个方法configureMessageConverters(),它会配置默认的MessageConverter public void configureMessageConverters(List<HttpMessageConverter<?>

  • 关于自定义Egg.js的请求级别日志详解

    Egg.js 是什么? Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本. 注:Egg.js 缩写为 Egg 背景 组织为了更好的对各个业务的请求日志进行统一的分析,制定了统一的日志打印规范,比如: [time][processId][traceId][userid] Hello World.... 统一格式之后,业务现有业务的日志工具打印出来的格式是无法满足该规范的,所以我们需要对此进行改造. 我们前端目前Node中间

  • springboot使用自定义注解实现aop切面日志

    平时我们在开发过程中,代码出现bug时为了更好的在服务器日志中寻找问题根源,会在接口的首尾打印日志,看下参数和返回值是否有问题.但是手动的logger.info() 去编写时工作量较大,这时我们可以使用AOP切面,为所有接口的首尾打印日志. 实现AOP切面日志一般有两种方式: 1.拦截所有接口controller,在首尾打印日志2.拦截指定注解的接口,为有该注解的接口首尾打印日志 我们尝试用自定义注解来实现AOP日志的打印,这样拥有更高的灵活性.废话不多说,我们开始 1. 导入切面需要的依赖包

  • SpringBoot 自定义注解异步记录复杂日志详解

    目录 1.背景 2.技术方案-自定义注解 2.1 注解介绍 2.2 元注解 2.3 实现自定义注解 3.技术方案-AOP切面 3.1 AOP术语解析 3.2 切入点表达式 3.3 ADVICE通知类型 3.4 技术实现 3.5 相关操作 4.高级操作 1.背景 最近接手一个任务,需要给当前项目加一个较为复杂的日志.有多复杂呢? 要有日志类型.不同日志类型要有不同的操作和备注等.作为小白的我最开始的做法是在业务层写代码记录日志,好处就是方便,坏处就是这种做法直接侵袭Service层,Service

  • SpringBoot通过自定义注解与异步来管理日志流程

    目录 一.前言 二.基础环境 1. 导入依赖 2. 编写yml配置 三.数据库设计 四.主要功能 1. 编写注解 2. 业务类型枚举 3. 编写切片 4. ip工具类 5. 事件发布 6. 监听者 五.测试 1. controller 2. service 3. dao 4. 测试 5. 数据库 六.总结 一.前言 我们在企业级的开发中,必不可少的是对日志的记录,实现有很多种方式,常见的就是基于AOP+注解进行保存,同时考虑到程序的流畅和效率,我们可以使用异步进行保存! 二.基础环境 1. 导入

  • springboot配置aop切面日志打印过程解析

    这篇文章主要介绍了springboot配置aop切面日志打印过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.SpringBoot Aop说明 1. Aop AOP(Aspect-Oriented Programming,面向切面编程),它利用一种"横切"的技术,将那些多个类的共同行为封装到一个可重用的模块.便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性. 2. AOP相关概念: Aspect

  • 使用Springboot自定义注解,支持SPEL表达式

    目录 Springboot自定义注解,支持SPEL表达式 1.自定义注解 2.使用AOP拦截方法,解析注解参数 自定义注解结合切面和spel表达式 自定义一个注解 自定义一个service类,在需要拦截的方法上加上@Log注解 写一个自定义切面 pom文件的依赖 测试 增加内容 Springboot自定义注解,支持SPEL表达式 举例,自定义redis模糊删除注解 1.自定义注解 import java.lang.annotation.ElementType; import java.lang.

  • SpringBoot自定义注解开发指南

    目录 一.Java注解(Annotation) 1.JDK基本注解 2.JDK元注解 二.自定义注解开发 1.含义 2.演示 三.完成切面日志操作 四.完成前端响应反应 总结 一.Java注解(Annotation) 含义:Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 1.JDK基本注解 @Override ——>重写 @Deprecated ——>已过时 @SuppressWarnings(value = "unchec

随机推荐