SpringBoot——AOP处理请求日志

本文介绍了如何使用Spring Boot中的AOP(面向切面编程)来处理请求日志,通过对比代码优化前后的情况,展示了AOP能有效减少代码重复,提高程序的可维护性和开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  这一篇文章咱们继续延续上一篇的博客《SpringBoot——问题讲解》之后的的续篇,咱们这篇文章主要的内容就是讲解AOP处理请求日志。

【AOP】

  AOP(Aspect Oriented Programming)面向切面编程,是一种编程的范式,与语言无关是一种程序设计思想,OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容。这种思想也同样的适用于:动态代理

【优点】

利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

【垂直处理和水平处理】

我们以记录每个Http请求为例:

垂直处理:


AOP进行水平处理:利用AOP进行方法拦截,红色的箭


  从图中看出,AOP对我们的业务的纵向走势不会造成阻碍作用,所以所面向切面编程是对面向对象编程的一种补充。上图是简单的一个AOP横向逻辑切入业务逻辑纵向逻辑的一个直挂展示,有些人会问?为什么要这样做?我们有那么多的横切行的必要吗?现在我们看看使用AOP可以帮助我们避免那些问题?


  aop解决了大量的代码重复。

  我需要做一个日志的功能,即需要在每条线上都进行日志的处理,我们是不是要这么写?


这样有很多条线中都包含了一段相同的代码,你怎么看?抽出来呗,作为公共的部分,被调用。


这样每个方法都和这个公共的功能类有关联关系,这里只是我们的抽出公共代码,解决了代码重复。我们需要做的是“解耦”,将业务类和这个公共的功能类之间的耦合解开。

【实现AOP】

一、代码优化前

maven的pom中添加引用

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


以其中的girlList()方法为例子:


显示结果:


这就是AOP面向切面编程的实现,但是我们发现一个问题,下图所示的代码出现了重复,这就是一种很不好的编程,显着特别的low,所有我们要对其进行优化



二、代码优化后:

注意:红色的框框是System.out.println用spring自带的SLF4J实现,蓝色的是抽出公共的部分


显示结果:


【结尾】

小伙伴们是不是发现用了AOP之后程序变得简单了好多,省略很多重复的代码呢?

下一篇文章我要进行统一异常的处理,欢迎继续关注哦!!!

### Spring Boot AOP 方法参数使用教程 #### 添加依赖 为了在Spring Boot项目中启用AOP功能,需引入`spring-boot-starter-aop`依赖。这使得开发者能够轻松利用面向切面编程来增强业务逻辑[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` #### 定义切面类 创建一个带有`@Aspect`注解的Java类作为切面,在其中定义切入点表达式以及通知方法。可以访问连接点的方法签名中的参数值: ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.ProceedingJoinPoint; @Aspect public class LoggingAspect { @Before("execution(* com.example.demo.controller.*.*(..)) && args(paramName)") public void logMethodArguments(String paramName){ System.out.println("Parameter value is " + paramName); } } ``` 上述代码展示了如何捕获特定包下所有控制器内的任何公共成员函数调用,并打印传入的第一个字符串类型的参数名。注意这里的`args()`用于匹配具有指定名称的实际参数列表项;如果希望获取更多参数,则可以在括号内继续添加其他形参声明[^1]。 #### 自动填充Controller层参数 对于某些场景下的通用操作(比如记录日志、设置默认值),可以通过AOP机制自动处理请求进入controller之前的工作。例如,当多个接口都需要接收相同结构的数据模型实例时,可考虑借助于环绕通知(`Around`)完成此类任务[^3]。 ```java @Around("@annotation(org.springframework.web.bind.annotation.GetMapping) && args(model,..)") public Object fillDefaultValues(ProceedingJoinPoint joinPoint, Model model)throws Throwable { // 设置默认属性... return joinPoint.proceed(); } ``` 此片段表示每当触发GET映射路径对应的处理器执行前都会先经过这段额外流程——即向视图模型对象里注入预设信息后再让原定动作按计划发生。 #### 常见问题解答 - **Q:** 如何解决因CGLIB代理造成的子类无法继承父级私有/保护级别成员变量的问题? - **A:** 可尝试调整为JDK标准接口型代理模式,或者重构源码使待共享资源变为公开静态常量等形式以便跨层次间正常传递数据[^4]。 - **Q:** 是否支持多线程环境下安全地读取修改被拦截的目标实体? - **A:** 是的,只要遵循良好的并发控制原则并合理运用同步锁机制就能保障事务一致性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值