使用Spring AOP添加统计时间的功能

简介: 使用Spring AOP添加统计时间的功能

最近有个需求,需要统计各个接口、类的方法的执行时间,但是要尽量不影响原来业务,不改变原有代码。

第一想到的就是使用AOP的方式来做,翻了一些资料,终于把问题解决了。这里整理一下:

Spring提供了4种实现AOP的方式:

1.经典的基于代理的AOP

2.@AspectJ注解驱动的切面

3.纯POJO切面

4.注入式AspectJ切面

我这里讲到的是使用@AspectJ注解驱动的方式,其他的可以自行研究一下。

首先我的项目是使用SpringMVC+Spring+Mybatis的结构,使用aop的方式,需要修改一下SpringMVC.xml配置。

1、增加AOP的XML命名空间和声明相关schema

命名空间:

xmlns:aop="http://www.springframework.org/schema/aop"

schema声明:

http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd


2、然后添加如下配置:

<!-- 开启切面编程功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

之后是编写我们的切面类:

package com.mysite.common.system;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.mysite.common.entity.TimeEntity;
import com.mysite.common.util.SendHearbeatUtil;
@Component
@Aspect
public class StatisticHelper {
private long startTime = 0;
  
  //对com.mysite.test包下面所有子包所有public方法有效,此方法不能有返回值
  @Pointcut("execution(public * com.mysite.test..*.*(..))")
  public void recordTime() {
  }
  @Before("recordTime()")
  public void before(JoinPoint jp) {
  startTime = System.currentTimeMillis();//获取访问时的当前时间
  }
  @AfterReturning("recordTime()")
  public void afterReturning(JoinPoint jp) {
  long process = System.currentTimeMillis() - startTime;//计算出调用方法返回的用时
  String className = jp.getThis().toString();//获取类名
  String methodName = jp.getSignature().getName(); // 获得方法名
  TimeEntity e = new TimeEntity();
  e.setClazz(className);
  e.setMethod(methodName);
  e.setTime(process);
  SendHearbeatUtil.pq.add(e);//把timeEntity放入SendHearbeatUtil中的队列中待处理
  }
}


这样我们的切面程序就已经完成。

在我们访问com.mysite.test包下面类的方法时,会启用切面统计。

Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合.

args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation

比如 @Pointcut("execution(public * com.mysite.test..*.*(..))")  可以写成:

@Pointcut("within(com.mysite.test..*)")

如果需要对多个包进行AOP,可以写成

@Pointcut("execution(public * com.mysite.test1..*.*(..)) or execution(public * com.mysite.test2..*.*(..))")

或者

@Pointcut("execution(public * com.mysite.test1..*.*(..)) || execution(public * com.mysite.test2..*.*(..))")


编写切面类的要点

@Aspect放在类头上,把这个类作为一个切面。

@Pointcut放在方法头上,定义一个可被别的方法引用的切入点表达式。

5种通知:

1、@Before,前置通知,放在方法头上。

2、@After,后置【finally】通知,放在方法头上。

3、@AfterReturning,后置【try】通知,放在方法头上,使用returning来引用方法返回值。

4、@AfterThrowing,后置【catch】通知,放在方法头上,使用throwing来引用抛出的异常。

5、@Around,环绕通知,放在方法头上,这个方法要决定真实的方法是否执行,而且必须有返回值。


相关文章
|
2月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
373 0
|
3月前
|
人工智能 监控 中间件
如何用go语言实现类似AOP的功能
本文介绍了如何在 Go 语言中借鉴 Java 的 AOP(面向切面编程)思想,通过 Gin 框架的中间件和函数包装机制实现日志记录、权限校验等横切关注点与业务逻辑的解耦。内容涵盖 AOP 的优点、Go 中的实现方式、Gin 中间件与 AOP 的异同,帮助开发者提升代码模块化与可维护性。
145 0
|
27天前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
306 2
|
3月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
3月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
3月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
6月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
228 32
|
6月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。