这是一个示例,如何使用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. R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器)、在编辑器中输出需要的数据生成最终的dataframe
  2. java输出数组中出现的次数最多的那个及次数
  3. python知网查重_用Python写了个检测抄袭/文章去重算法(nshash)
  4. 李飞飞点赞的NeurIPS新赛道,刚刚公布了第一批数据集benchmark入围名单
  5. 实验九:异常的抛出、捕获并处理
  6. 看完这些福利才知道,为什么说双12一定要出去浪
  7. junit可执行但控制层无法执行_Junit测试时ContextLoader.getCurrentWebApplicationContext()返回空值...
  8. jsf 项目_您将在下一个项目中使用JSF吗?
  9. “天才”少年!4位90后摘得全球顶尖数学大奖,90%获奖者不满30岁
  10. day43,使用朋友pyMySQL连接数据库
  11. 按代码行衡量编程进度就像按重量衡量飞机制造进度一样
  12. C++ 获取类成员虚函数地址
  13. mysql 4604,mysql--centos(7)安装
  14. 仅需6道题轻松掌握Python异常捕获 | Python技能树征题
  15. Android MTK 预制应用遇到的问题
  16. Python中使用snip问题
  17. uniapp使用IPA苹果支付
  18. Linux使用tar命令进行磁带备份
  19. 大学物理实验长度的测量实验报告_大学物理实验长度的测量实验总结
  20. vue3 +Ts后导包出现红色波浪线【vscode】

热门文章

  1. STC32G 单片机EEPROM 操作实例
  2. java基于token的认证,Java实现基于token认证
  3. 欧姆龙开发车载脉搏传感器,可实时检测驾驶员状态
  4. android 使用网络连接adb(需Root)
  5. CodeForces - 1305 C. Kuroni and Impossible Calculat(鸽巢原理)
  6. 用vsto(VBA)取消段落缩进
  7. 6中结构型设计模式的对比理解(Composite组合模式,Proxy代理模式,Flyweight享元模式,Facade门面模式,Bridge桥接模式,Decorator装饰器模式)
  8. 在 uniapp 中使用 fontawesome
  9. 导入销售订单时要求制定折扣物料
  10. 小程序 获取当前城市位置-高德地图