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

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

1)引入包依赖

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

[xhtml] view plaincopy

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-aop</artifactId>
  4. <version>2.5.6</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.aspectj</groupId>
  8. <artifactId>aspectjweaver</artifactId>
  9. <version>1.6.1</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.aspectj</groupId>
  13. <artifactId>aspectjrt</artifactId>
  14. <version>1.6.1</version>
  15. </dependency>

2)加上AOP的Spring配置文件

billing-spring-aop.xml:

[xhtml] view plaincopy

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  9. <bean id="openApiLogAspect" class="com.alibaba.itbu.billing.framework.aop.OpenApiLogAspect">
  10. </bean>
  11. <aop:config>
  12. <!-- 配置aspect切面类 -->
  13. <aop:aspect ref="openApiLogAspect">
  14. <!-- 配置pointcut,即切入点,对哪些类的哪些方法起到AOP的作用 -->
  15. <aop:pointcut id="EsbPriceService"
  16. expression="execution(* org.esb.biz.product.EsbPriceService.*(..))" />
  17. <aop:pointcut id="EsbProductService"
  18. expression="execution(* org.esb.biz.product.EsbProductService.*(..))" />
  19. <aop:pointcut id="IAuthorizeControllerService"
  20. expression="execution(* com.alibaba.bss.pc2.server.remoting.IAuthorizeControllerService.*(..))" />
  21. <aop:pointcut id="IOpenApiOrderItemService"
  22. expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiOrderItemService.*(..))" />
  23. <aop:pointcut id="IOpenApiBillingCollectService"
  24. expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiBillingCollectService.*(..))" />
  25. <aop:pointcut id="IOpenApiInvoiceService"
  26. expression="execution(* com.alibaba.itbu.billing.api.invoice.IOpenApiInvoiceService.*(..))" />
  27. <aop:pointcut id="IOpenApiChargeProductInfoService"
  28. expression="execution(* com.alibaba.itbu.billing.api.collect.IOpenApiChargeProductInfoService.*(..))" />
  29. <!-- 配置advice,这里采用在业务方法执行前后进行拦截 -->
  30. <aop:around method="logExecuteTime" pointcut-ref="EsbPriceService" />
  31. <aop:around method="logExecuteTime" pointcut-ref="EsbProductService" />
  32. <aop:around method="logExecuteTime" pointcut-ref="IAuthorizeControllerService" />
  33. <aop:around method="logExecuteTime" pointcut-ref="IOpenApiOrderItemService" />
  34. <aop:around method="logExecuteTime" pointcut-ref="IOpenApiBillingCollectService" />
  35. <aop:around method="logExecuteTime" pointcut-ref="IOpenApiInvoiceService" />
  36. <aop:around method="logExecuteTime" pointcut-ref="IOpenApiChargeProductInfoService" />
  37. </aop:aspect>
  38. </aop:config>
  39. </beans>

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

3)编写监控耗时的advice

OpenApiLogAspect:

  1. public class OpenApiLogAspect {
  2. private static LoggerService logger = LoggerFactory.getLogger(OpenApiLogAspect.class);
  3. public Object logExecuteTime(ProceedingJoinPoint joinPoint) throws Throwable{
  4. Date start = new Date();
  5. try{
  6. return joinPoint.proceed(joinPoint.getArgs());
  7. }catch(Exception err){
  8. throw err;
  9. }finally{
  10. Date end = new Date();
  11. logger.info("OpenApiExecuteTime:"+joinPoint.getSignature().getName()+" takes "+(end.getTime()-start.getTime())+"ms");
  12. }
  13. }
  14. }

此段代码就是基于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

基于Spring AOP实现对外接口的耗时监控的更多相关文章

  1. Spring AOP在函数接口调用性能分析及其日志处理方面的应用

    面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...

  2. 基于Spring aop写的一个简单的耗时监控

    前言:毕业后应该有一两年没有好好的更新博客了,回头看看自己这一年,似乎少了太多的沉淀了.让自己做一个爱分享的人,好的知识点拿出来和大家一起分享,一起学习. 背景: 在做项目的时候,大家肯定都遇到对一些 ...

  3. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  4. spring aop实现拦截接口请求打印日志

    在spring配置 1编写自己的注解类 2.编写注解解析类 3.配置spring aop代理 (下面我使用注解 如使用配置 配置切点即可,有两种代理默认jdk代理 设置true 为cglib代理) / ...

  5. 基于Spring AOP实现的权限控制

    1.AOP简介 AOP,面向切面编程,往往被定义为促使软件系统实现关注点的分离的技术.系统是由许多不同的组件所组成的,每一个组件负责一块特定的功能.除了实现自身核心功能之外,这些组件还经常承担着额外的 ...

  6. s2sh框架搭建(基于spring aop)

    对于spring aop 是如何管理事务的,请看一下:http://bbs.csdn.net/topics/290021423 1.applicationContext.xml <?xml ve ...

  7. 利用Spring AOP切面对用户访问进行监控

    开发系统时往往需要考虑记录用户访问系统查询了那些数据.进行了什么操作,尤其是访问重要的数据和执行重要的操作的时候将数记录下来尤显的有意义.有了这些用户行为数据,事后可以以用户为条件对用户在系统的访问和 ...

  8. 基于Spring Aop实现类似shiro的简单权限校验功能

    在我们的web开发过程中,经常需要用到功能权限校验,验证用户是否有某个角色或者权限,目前有很多框架,如Shiro Shiro有基于自定义登录界面的版本,也有基于CAS登录的版本,目前我们的系统是基于C ...

  9. Spring AOP 介绍与基于接口的实现

    热烈推荐:超多IT资源,尽在798资源网 声明:转载文章,为防止丢失所以做此备份. 本文来自公众号:程序之心 原文地址:https://mp.weixin.qq.com/s/vo94gVyTss0LY ...

随机推荐

  1. lintcode: 有效的括号序列

    题目: 有效的括号序列 给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and']', 判定是否是有效的括号序列. 样例 括号必须依照 "() ...

  2. Splunk常用命令

    重启/查看状态/停止splunk [root@localhost splunk]# /opt/splunk/bin/splunk restart / status / stop

  3. !!无须定义配置文件中的每个变量的读写操作,以下代码遍历界面中各个c#控件,自动记录其文本,作为配置文件保存

    namespace PluginLib{    /// <summary>    /// 遍历控件所有子控件并初始化或保存其值    /// </summary>    pub ...

  4. 写给系统管理员的25个PHP安全实践

    PHP是广泛使用的开源服务端脚本语言.通过HTTP或HTTPS协议,Apache Web服务允许用户访问文件或内容.服务端脚本语言的错误配置会导致各种问题.因此,PHP应该小心使用.以下是为系统管理员 ...

  5. python3.4安装suds

    使用suds访问webservice十分方便 python3.x安装suds会报错“No module named client” 在stackoverflow上找到了替代方法,安装suds-jurk ...

  6. php整理(一):变量和字符串

    PHP中的变量: 1. 定义:$符号来定义变量 2. 说明: (1)PHP弱语言,定义变量的时候不用声明类型,但是并不代表PHP没有数据类型 (2)变量名是区分大小写的,只能是数字,字母或者下划线 ( ...

  7. 修练8年C++面向对象程序设计之体会

    http://pcedu.pconline.com.cn/empolder/gj/c/0504/609482_1.html

  8. Windows下搭建MySql Master-Master Replication

    1.首先下载最新版的MySql Server (http://dev.mysql.com/downloads/windows/installer/) 2.安装MySql Server到两台机器上 My ...

  9. C++ 中字符串标准输入的学习及实验

    声明:下面实验中[]里面表示要输入里面的符号,[]符号本身并未输入 1.cin>> cin使用空白(空格.制表符.回车)来确定字符串的结束位置. cin会将换行符留在输入输出队列中. #i ...

  10. C# MySQL 数据库操作类

    using System; using System.Configuration; using System.Collections; using System.Data; using MySql.D ...