`
yinwufeng
  • 浏览: 287006 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于Spring AOP实现对外接口的耗时监控

阅读更多
AOP是Spring的核心,Spring不但自身对多种框架的集成是基于AOP,并且以非常方便的形式暴露给普通使用者。以前用AOP不多,主要是因为它以横截面的方式插入到主流程中,担心导致主流程代码不够清晰,定位问题不够方便,而在计费二期的项目里需要一个很适合用AOP来做的功能,就是要把对外接口和所调用的外部接口的耗时时间给记录下来,这个需求主要来自于计费一期的联调,常常发生系统间交互不够顺畅的情况,这就需要看每个接口调用时间来判定是谁的问题。

计费中心是整个后台系统的中间环节,与其他系统交互很多,这样的接口也很多,如果在每个接口的调用前后加时间记录比较繁琐,也影响主流程代码的美观,因此比较优雅的方式是用AOP,在不侵入原有代码的情况下,加上对接口调用的监控,并且可以在不需要的时候很容易移除。今天尝试了一下,感觉还挺好用,下面讲述一下实施步骤:

1)引入包依赖

本项目基于maven构建,因此加上包依赖比较方便,我需要的AOP依赖库有以下三个:

<dependency> 
  <groupId>org.springframework</groupId> 
  <artifactId>spring-aop</artifactId> 
  <version>2.5.6</version> 
</dependency> 
<dependency> 
  <groupId>org.aspectj</groupId> 
  <artifactId>aspectjweaver</artifactId> 
  <version>1.6.1</version> 
</dependency> 
<dependency> 
  <groupId>org.aspectj</groupId> 
  <artifactId>aspectjrt</artifactId> 
  <version>1.6.1</version> 
</dependency>  
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>2.5.6</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.6.1</version>
</dependency>



2)加上AOP的Spring配置文件

billing-spring-aop.xml:

<?xml version="1.0" encoding="UTF-8"?>     
<beans xmlns="http://www.springframework.org/schema/beans"    
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
xmlns:aop="http://www.springframework.org/schema/aop"    
xmlns:tx="http://www.springframework.org/schema/tx"    
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd    
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd    
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">    
   
<bean id="openApiLogAspect" class="com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect"> 
</bean>    
   
<aop:config>    
  <!-- 配置aspect切面类 -->    
  <aop:aspect ref="openApiLogAspect">    
   <!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 -->    
   <aop:pointcut id="EsbPriceService" 
    expression="execution(* org.esb.biz.product.EsbPriceService.*(..))" />    
   <aop:pointcut id="EsbProductService" 
    expression="execution(* org.esb.biz.product.EsbProductService.*(..))" />    
   <aop:pointcut id="IAuthorizeControllerService" 
    expression="execution(* com.alibaba.bss.pc2.server.remoting.IAuthorizeControllerService.*(..))" />      
   <aop:pointcut id="IOpenApiOrderItemService" 
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiOrderItemService.*(..))" />   
   <aop:pointcut id="IOpenApiBillingCollectService" 
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiBillingCollectService.*(..))" />   
   <aop:pointcut id="IOpenApiInvoiceService" 
    expression="execution(* com.alibaba.itbu.billing.api.invoice.IOpenApiInvoiceService.*(..))" />   
   <aop:pointcut id="IOpenApiChargeProductInfoService" 
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiChargeProductInfoService.*(..))" />       
   <!-- 配置advice,这里采用在业务方法执行前后进行拦截 -->    
   <aop:around method="logExecuteTime" pointcut-ref="EsbPriceService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="EsbProductService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="IAuthorizeControllerService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiOrderItemService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiBillingCollectService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiInvoiceService" /> 
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiChargeProductInfoService" /> 
  </aop:aspect>               
</aop:config>    
 
</beans>  
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 

<bean id="openApiLogAspect" class="com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect">
</bean> 

<aop:config> 
  <!-- 配置aspect切面类 --> 
  <aop:aspect ref="openApiLogAspect"> 
   <!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 --> 
   <aop:pointcut id="EsbPriceService"
    expression="execution(* org.esb.biz.product.EsbPriceService.*(..))" /> 
   <aop:pointcut id="EsbProductService"
    expression="execution(* org.esb.biz.product.EsbProductService.*(..))" /> 
   <aop:pointcut id="IAuthorizeControllerService"
    expression="execution(* com.alibaba.bss.pc2.server.remoting.IAuthorizeControllerService.*(..))" />   
   <aop:pointcut id="IOpenApiOrderItemService"
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiOrderItemService.*(..))" />
   <aop:pointcut id="IOpenApiBillingCollectService"
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiBillingCollectService.*(..))" />
   <aop:pointcut id="IOpenApiInvoiceService"
    expression="execution(* com.alibaba.itbu.billing.api.invoice.IOpenApiInvoiceService.*(..))" />
   <aop:pointcut id="IOpenApiChargeProductInfoService"
    expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiChargeProductInfoService.*(..))" />    
   <!-- 配置advice,这里采用在业务方法执行前后进行拦截 --> 
   <aop:around method="logExecuteTime" pointcut-ref="EsbPriceService" />
   <aop:around method="logExecuteTime" pointcut-ref="EsbProductService" />
   <aop:around method="logExecuteTime" pointcut-ref="IAuthorizeControllerService" />
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiOrderItemService" />
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiBillingCollectService" />
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiInvoiceService" />
   <aop:around method="logExecuteTime" pointcut-ref="IOpenApiChargeProductInfoService" />
  </aop:aspect>            
</aop:config> 

</beans>


我是基于配置完成AOP接入,这样做的好处是不需要对原有主流程代码有任何浸入,并且也比较容易移除本AOP的拦截,这段代码主要就是配置aspect、pointcut和advice

3)编写监控耗时的advice

OpenApiLogAspect:

public class OpenApiLogAspect {  
private static LoggerService logger = LoggerFactory.getLogger(OpenApiLogAspect.class);  
public Object logExecuteTime(ProceedingJoinPoint joinPoint) throws Throwable{  
  Date start = new Date();  
  try{  
   return joinPoint.proceed(joinPoint.getArgs());  
  }catch(Exception err){  
   throw err;  
  }finally{  
   Date end = new Date();  
   logger.info("OpenApiExecuteTime:"+joinPoint.getSignature().getName()+" takes "+(end.getTime()-start.getTime())+"ms");  
  }  
}  
}  
public class OpenApiLogAspect {
private static LoggerService logger = LoggerFactory.getLogger(OpenApiLogAspect.class);
public Object logExecuteTime(ProceedingJoinPoint joinPoint) throws Throwable{
  Date start = new Date();
  try{
   return joinPoint.proceed(joinPoint.getArgs());
  }catch(Exception err){
   throw err;
  }finally{
   Date end = new Date();
   logger.info("OpenApiExecuteTime:"+joinPoint.getSignature().getName()+" takes "+(end.getTime()-start.getTime())+"ms");
  }
}
}



此段代码就是基于around的方式来拦截接口调用,在实际调用的前后加上时间记录,并最后在日志里打印出时间差。其中joinPoint.proceed(joinPoint.getArgs());是对实际接口的调用。

4)使监控可以配置化

此功能只会在调试阶段使用,并不需要在生产环境中运行,因此需要可以配置是否监控接口。实施这个配置化很简单,只需要通过配置决定是否把aop spring的配置文件加入到容器里就可以了,因此在总容器applicationContext.xml.vm里加上如下代码:

#if(${monitor_openapi_showTime}=="true")
<import resource="classpath*:bean/billing-spring-aop.xml" />
#end

在编译打包过程中会根据变量monitor_openapi_showTime来决定是否把billing-spring-aop.xml引入进来

5)运行效果

在监控开启的情况下,若发生接口调用,能从日志里看到如下记录:

2010-01-08 18:30:13,197 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO  com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 71ms
2010-01-08 18:30:27,188 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO  com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 0ms
2010-01-08 18:30:37,838 [OpenApiLogAspect.java:20] [com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect] INFO  com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect :: OpenApiExecuteTime:installOrderItem takes 1ms


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cutesource/archive/2010/01/09/5163467.aspx
分享到:
评论

相关推荐

    Java利用spring aop进行监测方法执行耗时

    代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 Spring AOP 进行方法耗时监测,可以在不修改业务逻辑代码的...

    spring AOP的运用

    4. 性能监控:在方法执行前后记录耗时,用于性能分析。 总的来说,Spring AOP提供了一种优雅的方式来处理横切关注点,使得业务代码更专注于核心功能,提高了代码的可读性和可维护性。通过源码学习和实际操作,我们...

    Spring Boot Aspect 切面 AOP 拦截器 Interceptor 监控control请求耗时

    不同于HandlerInterceptor,MethodInterceptor是基于代理的AOP,适用于拦截任何由Spring管理的对象,而不仅仅是控制器。通过实现`org.aopalliance.intercept.MethodInterceptor`接口,并重写`invoke()`方法,我们...

    Spring AOP 实例

    总结,Spring AOP通过定义切面、切点、通知等概念,实现了在不修改原有代码的情况下增强程序功能,提高了代码的可维护性和复用性。在实际开发中,可以根据业务需求灵活应用AOP,例如日志记录、性能监控、事务管理等...

    SpringBoot基于注解实现Aop

    通过以上内容,你已经掌握了如何在Spring Boot中基于注解实现AOP的基本步骤。在实际项目中,你可以结合自己的需求,灵活运用这些知识来实现诸如日志记录、事务管理、性能监控等功能。在`aop-guide`这个项目中,你...

    spring注解aop demo

    Spring注解AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的一个重要特性,它使得开发者可以在不修改原有代码的情况下,通过添加注解来实现横切关注点,如日志、事务管理等。下面我们将深入探讨...

    Spring AOP 注解方式

    在Spring AOP中,我们可以利用注解来实现切面,使得代码更加简洁、易读。本篇文章将深入探讨如何使用注解方式在Spring AOP中实现内部方法的拦截。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它...

    Spring AOP详细介绍.docx

    }}(2)Service 接口与实现类如 UserService.java 和 UserServiceImpl.java,其中 UserService 接口中定义了需要进行 AOP 监控的方法,如 getUserInfo。(3)配置类:在 Spring 的配置文件中,我们需要启用 @AspectJ 的...

    sping_aop实现

    下面我们将深入探讨Spring AOP的实现及其相关知识点。 1. **AOP基本概念** - **切面(Aspect)**:AOP的核心概念,它包含了横切关注点和这些关注点的实现。 - **连接点(Join Point)**:程序执行过程中的特定点...

    9Spring AOP 盗梦空间之四——Around

    在"Spring_AOP_Annotation"这个压缩包文件中,可能包含了关于如何在Spring中使用注解来配置和实现AOP,特别是环绕通知的示例代码和文档。通过研究这些资源,开发者可以更好地理解和应用Spring AOP的环绕通知功能,...

    SpringAOP的日志拦截示例

    首先,我们需要创建一个拦截器类,这个类通常会实现Spring的`MethodBeforeAdvice`、`AfterReturningAdvice`或`ThrowsAdvice`接口,或者自定义一个Advisor。在这个案例中,文件名为`LogInterceptor.java`的类可能是...

    spring aop

    在IT行业中,Spring AOP(面向切面编程)是一个强大的工具,它允许我们在不修改源代码的情况下,对程序的行为进行增强或监控。本篇将详细阐述Spring AOP在记录用户操作日志方面的重要应用,以及如何利用@Aspect注解...

    springboot基于AOP将web请求写入日志

    在Spring Boot中,AOP(面向切面编程)是一种强大的工具,可以让我们在不修改业务代码的情况下,实现如日志记录、性能监控等横切关注点。本教程将引导新手理解如何利用AOP来记录Web请求日志。下面将详细阐述这个过程...

    springMVC AOP拦截拦截Controller等实现日志管理

    在Spring MVC中,AOP(面向切面编程)是一种强大的工具,可以让我们在不修改代码的情况下,对程序的特定部分进行增强,例如日志记录、事务管理或性能监控。在这个场景中,我们将讨论如何利用AOP来实现Controller的...

    Spring Boot 实现 AOP 动态热插拔功能 教程配套源码

    我们以一个例子来说明一下为什么需要 AOP 动态热插拔:我们系统有一个 AOP 切面,它负责了记录用户传递参数、执行时间、接口返回结果,默认是不开启的,现在因为某些原因需要检测某个接口参数接收情况 + 耗时 + 返回...

    利用Spring AOP记录方法的执行时间

    在Spring框架中,AOP通过切面(Aspect)和通知(Advice)实现。切面是定义关注点的模块,而通知则是切面中的具体行为,如方法调用前后执行的代码。 在传统的做法中,我们可能会在每个需要监控的方法中手动添加开始...

    实验报告3-资料.rar

    实验报告3-Spring AOP是关于使用Spring框架的面向切面编程(AOP)功能来实现数据访问对象(DAO)层方法的执行时间统计。在Java开发中,Spring AOP是一种强大的工具,它允许程序员在不修改源代码的情况下,通过添加...

    aop相关开发包

    5. org.springframework.aop.jar:这是Spring框架的AOP模块,提供了基于代理的AOP实现。Spring AOP允许在不改变原有代码的情况下,通过定义切面和通知来增强功能。它支持方法前、后、异常、最终以及环绕通知,并且...

    spring-aop-practice

    Spring AOP在默认情况下,如果目标对象实现了接口,会优先选择JDK动态代理;如果没有实现接口,则会切换到CGLIB代理。Spring AOP提供了更高级的切面概念,可以定义切点(Pointcut)、通知(Advice)和切面(Aspect...

Global site tag (gtag.js) - Google Analytics