这是一个示例,如何使用StopWatch通过注释专用方法来设置多个测量。 使用非常有用和非常简单的方法来测量例如多个embedded式呼叫/操作的服务呼叫等等。

StopWatchHierarchy

package ch.vii.spring.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; @Component public class ProfilingMethodInterceptor implements MethodInterceptor { private static final Logger log = LoggerFactory.getLogger(ProfilingMethodInterceptor.class); public Object invoke(MethodInvocation invocation) throws Throwable { if (log.isInfoEnabled()) { String stopWatchName = invocation.getMethod().toGenericString(); StopWatchHierarchy stopWatch = StopWatchHierarchy.getStopWatchHierarchy(stopWatchName); String taskName = invocation.getMethod().getName(); stopWatch.start(taskName); try { return invocation.proceed(); } finally { stopWatch.stop(); } } else { return invocation.proceed(); } } static class StopWatchHierarchy { private static final ThreadLocal stopwatchLocal = new ThreadLocal(); private static final IndentStack indentStack = new IndentStack(); static StopWatchHierarchy getStopWatchHierarchy(String id) { StopWatchHierarchy stopWatch = stopwatchLocal.get(); if (stopWatch == null) { stopWatch = new StopWatchHierarchy(id); stopwatchLocal.set(stopWatch); } return stopWatch; } static void reset() { stopwatchLocal.set(null); } final StopWatch stopWatch; final Stack stack; StopWatchHierarchy(String id) { stopWatch = new StopWatch(id); stack = new Stack(); } void start(String taskName) { if (stopWatch.isRunning()) { stopWatch.stop(); } taskName = indentStack.get(stack.size) + taskName; stack.push(taskName); stopWatch.start(taskName); } void stop() { stopWatch.stop(); stack.pop(); if (stack.isEmpty()) { log.info(stopWatch.prettyPrint()); StopWatchHierarchy.reset(); } else { stopWatch.start(stack.get()); } } } static class Stack { private int size = 0; String elements[]; public Stack() { elements = new String[10]; } public void push(String e) { if (size == elements.length) { ensureCapa(); } elements[size++] = e; } public String pop() { String e = elements[--size]; elements[size] = null; return e; } public String get() { return elements[size - 1]; } public boolean isEmpty() { return size == 0; } private void ensureCapa() { int newSize = elements.length * 2; elements = Arrays.copyOf(elements, newSize); } } static class IndentStack { String elements[] = new String[0]; public String get(int index) { if (index >= elements.length) { ensureCapa(index + 10); } return elements[index]; } private void ensureCapa(int newSize) { int oldSize = elements.length; elements = Arrays.copyOf(elements, newSize); for (int i = oldSize; i < elements.length; i++) { elements[i] = new String(new char[i]).replace("\0", "| "); } } } }

顾问

package ch.vii.spring.aop; import java.lang.reflect.Method; import org.aopalliance.aop.Advice; import org.springframework.aop.Pointcut; import org.springframework.aop.support.AbstractPointcutAdvisor; import org.springframework.aop.support.StaticMethodMatcherPointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ProfilingAdvisor extends AbstractPointcutAdvisor { private static final long serialVersionUID = 1L; private final StaticMethodMatcherPointcut pointcut = new StaticMethodMatcherPointcut() { public boolean matches(Method method, Class> targetClass) { return method.isAnnotationPresent(ProfileExecution.class); } }; @Autowired private ProfilingMethodInterceptor interceptor; public Pointcut getPointcut() { return this.pointcut; } public Advice getAdvice() { return this.interceptor; } }

ProfileExecution注释

package ch.vii.spring.aop; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Inherited public @interface ProfileExecution { }

注释你的代码

package ch.vii.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ch.vii.spring.aop.ProfileExecution; @Component public class Bean { @Autowired InnerBean innerBean; @ProfileExecution public void foo() { innerBean.innerFoo(); innerBean.innerFoo2(); innerBean.innerFoo(); } } public class InnerBean { @Autowired InnerInnerBean innerInnerBean; @ProfileExecution public void innerFoo() { } @ProfileExecution public void innerFoo2() { innerInnerBean.innerInnerFoo(); innerInnerBean.innerInnerFoo(); innerInnerBean.innerInnerFoo(); } }

产量

09:58:39.627 [main] INFO cvsaop.ProfilingMethodInterceptor - StopWatch 'public void ch.vii.spring.Bean.foo()': running time (millis) = 215 ----------------------------------------- ms % Task name ----------------------------------------- 00018 008 % foo 00026 012 % | innerFoo 00001 000 % foo 00016 007 % | innerFoo2 00038 018 % | | innerInnerFoo 00000 000 % | innerFoo2 00024 011 % | | innerInnerFoo 00028 013 % | innerFoo2 00024 011 % | | innerInnerFoo 00029 013 % | innerFoo2 00000 000 % foo 00011 005 % | innerFoo 00000 000 % foo

java 秒表_Java的秒表类相关推荐

  1. java 秒表_JAVA计时器秒表程序代码

    <JAVA计时器秒表程序代码>由会员分享,可在线阅读,更多相关<JAVA计时器秒表程序代码(7页珍藏版)>请在人人文库网上搜索. 1.Java计时器(秒表)功能:能实现计时,暂 ...

  2. java分装_Java ——Number Math 类 装箱 拆箱 代码块

    本节重点思维导图 当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等 int a = 5000;float b = 13.65f;byte c = 0x4 ...

  3. java缺_java – 缺少主类

    我正试图运行"Head First Java"一书中的第一个例子; public class MyFirstApp { public static void main (Strin ...

  4. java 泛化_Java语言class类用法及泛化(详解)

    这篇文章主要介绍了Java语言class类用法及泛化(详解),大家都知道Java程序在运行过程中,对所有的对象进行类型标识,也就是RTTI.这项信息记录了每个对象所属的类.虚拟机通常使用运行时类型信息 ...

  5. java程序设计_Java程序设计-Object类(笔记)

    1.(java.lang.Object类,代码情景引入)(API演示Object类的内容) 总结: 1)Object类是所有Java类的根父类 2)如果在类的声明中未使用extends关键字指明其父类 ...

  6. java闭锁_Java并发工具类(闭锁CountDownLatch)

    闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态. CountDownLatch是一种灵活的闭锁实现,它可以使一个或者多个线程等待一组事件的发生. 闭锁状态包含一个计数器,该计数器被初始化为 ...

  7. 学生类java程序_java 创建学生类

    创建一个学生类,属性包括学生姓名,学号,性别及4门课成绩,方法包括计算学生总分和显示学生的相关信息. import java.util.*; class Student{ String name; S ...

  8. java 栅栏_Java 并发工具类(栅栏 CyclicBarrier )

    CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行地执行工作,然后在下一个步骤之前等待,直到所有任务都完成.栅栏和闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. ...

  9. java 抽奖_java抽奖工具类:按概率抽奖

    在一些抽奖活动中,会有按概率抽取奖品的操作,本文将提供一个抽奖概率的解决方案. 假设抽奖集合如下: 奖品id 概率 1 10% 2 10% 3 20% 4 20% 生成集合 生成的连续集合为{(0.0 ...

最新文章

  1. NPOI导入导出EXCEL通用类,可直接使用在WinForm项目中
  2. Java基础学习总结(8)——super关键字
  3. python基础之异常处理
  4. 如何测试网络视频服务器(DVS)
  5. 达人篇:2.1)零缺陷管理法;
  6. oracle什么时候需要commit
  7. HDU 3046 Pleasant sheep and big big wolf 最小割
  8. 如何解决ipconfig、ping不是内部或外部命令
  9. linux之file命令总结
  10. 【渝粤题库】国家开放大学2021春3929电气安全技术题目
  11. java序列化错在哪里_Spark序列化错误:java.io.NotSerializableException
  12. python alphago_如何利用 Python 打造一款简易版 AlphaGo
  13. (Scrapy框架)爬虫获取新冠疫情数据升级版 | 爬虫案例
  14. CondConv: Conditionally Parameterized Convolutions for Efficient Inference论文解读
  15. 案例解读 | 重视管理会计,让永辉超市从生鲜市场破局
  16. C# GDI+ 画心形 跳动动画
  17. 是谁在我的心里打了个结(七)投标书
  18. 第四十六讲 设备驱动kobject
  19. 使用DirectDraw直接显示YUV视频数据
  20. 2020无人用的邮箱和密码大全_2020抖音文案大全:这4大抖音文案技巧,点赞100w的账号都在用...

热门文章

  1. Ubuntu18安装VTK8.2
  2. 休假管理系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  3. 独家 | 大数据提升政府决策力的实践与案例分析(附PPT和视频)
  4. CEPH离线部署(纯内网)
  5. 【PythonGUI小程序】相信我,这是最in的n种骰子梭哈小游戏新玩法,好玩到丧心病狂~(文中有惊喜)
  6. python内置函数:enumerate用法总结
  7. mysql 自定义函数报错_Mysql自定义函数报错解决方法 | 学步园
  8. Mysql去重查询(根据指定字段去重)
  9. 零编码制作报表真的可能吗?
  10. 排列组合( Lindström–Gessel–Viennot lemma 定理)