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. Unity3d游戏中添加移动MM支付SDK问题处理

    原地址:http://www.tuicool.com/articles/I73QFb 由于移动mm的SDK将部分资源文件放在jar包中,导致Unity无法识别,提示failed to find res ...

  2. Properties --- C++读配置信息的类(一)

    http://blog.csdn.net/billow_zhang/article/details/4304980 在开发实践中,积累了一些通用的C++ 类库,在此写出来给大家分享.也希望能给出更好的 ...

  3. Oracle 体系结构2 - 共享和专用服务器

    1. 怎么查看自己的oracle是共享还是专用服务器 2. 怎么修改设置 3.各有什么优缺点 4.适用环境 对于专用服务器,每一个数据库连接,oracle都会分配一个专门的进程为其服务 oracle@ ...

  4. Project Euler 92:Square digit chains 平方数字链

    题目 Square digit chains A number chain is created by continuously adding the square of the digits in ...

  5. lintcode :Count and Say 报数

    题目: 报数 报数指的是,按照其中的整数的顺序进行报数,然后得到下一个数.如下所示: 1, 11, 21, 1211, 111221, ... 1 读作 "one 1" -> ...

  6. C#中SaveFileDialog 和OpenFileDialog 的用法

    1.OpenFileDialog private void btnOpen_Click(object sender, EventArgs e) { OpenFileDialog ofd = new O ...

  7. *Linux之rm命令

    自己瞅: [root@winner ~]# rm --help//rm-->remove用法:rm [选项]... 文件... 删除 (unlink) 文件. -f, --force 强制删除. ...

  8. 62. Unique Paths

    题目: A robot is located at the top-left corner of a m x ngrid (marked 'Start' in the diagram below). ...

  9. SoapUI test WCF

    http://blogs.msdn.com/b/nabeelp/archive/2008/03/07/obscure-error-addressfilter-mismatch-at-the-endpo ...

  10. Map集合案例

    1.获取字符串中每一个字母出现的次数. 比如"aababcabcdabcde",结果为:a(5)b(4)c(3)d(2)e(1) 分析如下: package mapexercise ...