运用Spring Aop+注解实现日志记录

目录
  • 1. 介绍
  • 2. 实践
    • 2.1 定义注解
    • 2.2 切面类
    • 2.3 编写测试方法
    • 2.4 运行结果
  • 3. 总结
  • 4. 参考文章

1. 介绍

我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到的。在日常项目中,我们也会经常使用IOC控制反转,但是却感觉AOP很少会运用到。其实AOP大有用处,甚至可以让你偷偷懒。

举一个例子,假如现在要让你记录每一个请求的请求IP,请求的方法,请求路径,请求的参数,返回参数,你会怎么做?你会想,那简单啊,我直接 log.info("xxxx") 输出日志不行吗,简单!可是你要想清楚,每个请求请求的方法不一定是同一个,有一些请求可能请求编辑方法,另外一些请求可能请求登录方法,这么多方法,你每一个方法下面都重复写了差不多6,7行重复代码,你觉得这好吗?

这里,如果我们使用Aop来记录日志,那是再好不过了。我们可以看看一个方法的执行过程来理解AOP。

下面再来看使用AOP后的执行过程。

AOP是面向切面编程,面向切面思想就是让我们把程序想象成一条一条管道连接起来的大管道,而AOP就是在管道和管道之间的过滤网,能够在不影响管道的情况下对管道中传输的数据进行记录,修改。

使用AOP我们可以很方便地进行操作日志记录,性能日志记录,请求日志记录,事务操作,安全管理等。这么说可能很抽象,再详细点说就是各种日志记录我们可以利用AOP来进行记录,而不用在业务逻辑代码中插入,安全管理就是我们可以在请求进来前对请求中的数据进行解密,在请求返回的时候对数据进行加密。这么说AOP很像Java里面的拦截器,过滤器和监听器的结合。

具体AOP的原理就不细讲了,那是另外一篇文章了,有关于动态代理。

2. 实践

说了这么多,大白话就是AOP能让我们在不影响原代码的基础上,对代码功能进行添加,修改

在实现日志记录功能前,我们要先复习一下 Spring Aop 里面的通知顺序(连接点,通知还不知道是什么的,先去B站看一下Spring初级教程)。

先把Aop的starter依赖添加进pom文件中。

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

2.1 定义注解

那现在我们来自定义一个注解,目的是标注该注解的方法将会记录调用该方法的请求信息

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface MyLog {
    String value() default "";
}

注解不是本篇重点,有兴趣的童鞋可以搜一下。

2.2 切面类

定义我们的日志记录切面类,切面类中记录请求的信息。

@Component
@Aspect
@Slf4j
public class LogAspect {

    //切入点为自定义注解
    @Pointcut("@annotation(com.example.springaopdemo.demo2.MyLog)")
    public void MyLog(){}

    @Before("MyLog()")
    public void Before(JoinPoint jp){
        //获取HttpServletRequest对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert requestAttributes != null;
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("==========请求信息==========");
        log.info("请求链接 : {}",request.getRequestURL().toString());
        log.info("Http Method : {}",request.getMethod());
        log.info("Class Method : {}.{}",jp.getSignature().getDeclaringTypeName(),jp.getSignature().getName());
        log.info("Ip : {}",request.getRemoteAddr());
        log.info("Args : {}", Arrays.asList(jp.getArgs()));
    }

    @Around("MyLog()")
    public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        log.info("执行时间 : {} ms", System.currentTimeMillis() - startTime);
        log.info("返回参数 : {}", result);
        return result;
    }
}

通过 @Around 环绕通知我们可以进行简单的性能记录,如果加上 Oshi 我们甚至可以记录执行该方法前后的CPU,内存占用率。

Oshi是Java的免费基于JNA的操作系统和硬件信息库,Github地址是:https://github.com/oshi/oshi
它的优点是不需要安装任何其他本机库,并且旨在提供一种跨平台的实现来检索系统信息,例如操作系统版本,进程,内存和CPU使用率,磁盘和分区,设备,传感器等。

2.3 编写测试方法

编写一个简单的请求,请求需要一个User对象的请求体,返回一个Map结果。

@RestController
@Slf4j
public class Controller {

    @PostMapping("/test")
    @MyLog
    public Map<String, Object> testAop(@RequestBody User user){
        Map<String,Object> map = new HashMap<>();
        map.put("code",200);
        map.put("errorMsg","success");
        return map;
    }
}

2.4 运行结果

使用IDEA自带的Http Client来测试api

结果:

可以看到通过利用AOP,我们没有修改Controller中的代码,就可以实现对Controller中每个方法请求信息的日志记录功能。

而且我们还能够指定该切面类是在生产环境还是开发环境下生效,只需要在切面类上添加注解。

@Profile({"dev"})

然后在配置文件中定义 spring.profiles.active 的属性即可。

3. 总结

因为学习了Spring后,虽然知道有AOP这个东西,但是却从来没有真正的在实际项目中运用,这几天研究日志记录,却发现AOP在日志记录中的妙用,甚至可以利用AOP在对代码无侵入的情况下,进行参数数据的加密和解密操作。但是,虽然说AOP使用方便,但是不能够滥用,毕竟AOP底层使用动态代理,而动态代理要做到对方法的修改就肯定要使用到反射,反射会对性能有影响。

4. 参考文章

(7 封私信 / 66 条消息) 在一个完整的项目中,会用AOP技术么,能用简单易懂的方式说明下什么是AOP么? - 知乎 (zhihu.com)

【SpringBoot】AOP应用实例_sysu_lluozh-CSDN博客

(20条消息) Springboot Aop 自定义注解、切面_张同学的博客-CSDN博客_springboot 自定义注解切面

到此这篇关于运用Spring Aop,一个注解实现日志记录的文章就介绍到这了,更多相关Spring Aop日志记录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springMVC自定义注解,用AOP来实现日志记录的方法

    需求背景 最近的一个项目,在项目基本完工的阶段,客户提出要将所有业务操作的日志记录到数据库中,并且要提取一些业务的关键信息(比如交易单号)体现在日志中. 为了保证工期,在查阅了资料以后,决定用AOP+自定义注解的方式来完成这个需求. 准备工作 自定义注解需要依赖的jar包有 aspectjrt-XXX.jar ,aspectjweaver-XXX.jar,XXX代表版本号. 自定义注解 在项目下单独建立了一个log包,来存放日志相关的内容 **.common.log.annotation //自

  • Spring AOP实现复杂的日志记录操作(自定义注解)

    目录 Spring AOP复杂的日志记录(自定义注解) 第一步 第二步 第三步 第四步 多个注解可以合并成一个,包括自定义注解 比如说SpringMVC的注解 Spring AOP复杂的日志记录(自定义注解) 做项目中,业务逻辑要求只要对数据库数据进行改动的都需要记录日志(增删改),记录的内容有操作者.操作的表名及表名称.具体的操作,以及操作对应的数据. 首先想到的就是Spring 的AOP功能.可是经过一番了解过后,发现一般的日志记录,只能记录一些简单的操作,例如表名.表名称等记录不到. 于是

  • 运用Spring Aop+注解实现日志记录

    目录 1. 介绍 2. 实践 2.1 定义注解 2.2 切面类 2.3 编写测试方法 2.4 运行结果 3. 总结 4. 参考文章 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到的.在日常项目中,我们也会经常使用IOC控制反转,但是却感觉AOP很少会运用到.其实AOP大有用处,甚至可以让你偷偷懒. 举一个例子,假如现在要让你记录每一个请求的请求IP,请求的方法,请求路径,请求的参数,返回参数

  • 在springboot中使用AOP进行全局日志记录

    目录 前言 1. spring AOP 是什么? 2.spring AOP 能做什么? 3.spring AOP 我能用 AOP 解决什么问题? 一.引入依赖,增加自定义注解 1.引入 maven 依赖 2.增加自定义注解 OperationLog 二.为自定义注解编写切面实现 三.使用自定义日志注解 前言 此前项目上需要对用户的操作进行日志记录,以便后续追踪问题,所以就学习了使用 spring AOP 来进行日志记录. 1. spring AOP 是什么? spring 的两大核心就是 IOC

  • Spring AOP注解失效的坑及JDK动态代理

    @Transactional @Async等注解不起作用 之前很多人在使用Spring中的@Transactional, @Async等注解时,都多少碰到过注解不起作用的情况. 为什么会出现这些情况呢?因为这些注解的功能实际上都是Spring AOP实现的,而其实现原理是通过代理实现的. JDK动态代理 以一个简单的例子理解一下JDK动态代理的基本原理: //目标类接口 public interface JDKProxyTestService { void run(); } //目标类 publ

  • spring aop注解配置代码实例

    本文实例为大家分享了spring aop注解配置的具体代码,供大家参考,具体内容如下 Demo.java package cn.itcast.e_annotation; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springfra

  • Spring AOP + 注解实现统一注解功能

    1. 概述 在一般系统中,当我们做了一些重要的操作时,如登陆系统,添加用户,删除用户等操作时,我们需要将这些行为持久化.本文我们通过Spring AOP和Java的自定义注解来实现日志的插入.此方案对原有业务入侵较低,实现较灵活 2. 日志的相关类定义 我们将日志抽象为以下两个类:功能模块和操作类型 使用枚举类定义功能模块类型ModuleType,如学生.用户模块 public enum ModuleType { DEFAULT("1"), // 默认值 STUDENT("2

  • Spring AOP注解案例及基本原理详解

    切面:Aspect 切面=切入点+通知.在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解.切面负责将 横切逻辑(通知) 编织 到指定的连接点中. 目标对象:Target 将要被增强的对象. 连接点:JoinPoint 可以被拦截到的程序执行点,在spring中就是类中的方法. 切入点:PointCut 需要执行拦截的方法,也就是具体实施了横切逻辑的方法.切入点的规则在spring中通过AspectJ pointcut expression language来描述.

  • Spring Aop注解实现

    目录 Spring-aop-理论知识 Spring-Aop-注解实现 项目结构图 具体步骤: 1.创建maven 项目 导入依赖 创建好项目结构 2.写一个接口 及 其实现类 3.切面类 4.application.xml 文件 测试 总结 Spring-aop-理论知识 Spring-Aop-注解实现 项目结构图 具体步骤: 1.创建maven 项目 导入依赖 创建好项目结构 <dependencies> <dependency> <groupId>org.proje

  • spring AOP自定义注解方式实现日志管理的实例讲解

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven /> <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 --> <context:component-scan base-package=&qu

随机推荐