🍃增强StopWatch类监控代码的执行耗时
背景
在业务开发中,我们经常需要对代码执行的耗时进行监控。Spring
有一个org.springframework.util.StopWatch
工具类实现了该功能。
基本使用方式如下:
1 | private static void testSpringStopWatch() { |
除了我们需要执行的业务逻辑代码之外,我们还需要在finally
代码块中手动调用stop
方法,然后对执行耗时进行输出打印。
这样的代码多起来就显得很重复了。我们得想个办法少写点代码qwq
~
如何对方法进行增强
增强一个Java
类中的方法有几种方式?
- 继承:只有在能够控制这个类的构造器的时候(即不能全部是
private
修饰的构造器),才可以使用继承。 - 装饰模式:装饰对象和被装饰对象都要实现相同的接口,装饰对象中需要获取被装饰对象的引用。
- 动态代理:
JDK
动态代理:需要被增强类实现一个接口。cglib
动态代理:不需要被增强类实现一个接口,内部通过继承生成子类的方式对被代理类进行增强。所以被代理类最好不要声明成final
。
对StopWatch
进行增强
增强方式
由于监控代码执行耗时需要能监控任意一小段代码执行的耗时,所以我们不能使用AOP对整个方法进行增强。而装饰模式需要在装饰对象中获取被装饰对象的引用,适合有很多种增强的情况下使用,例如JDK
的IO
流体系。这里我只需要单一的对StopWatch
类进行增强,所以我选择使用继承的方式。
增强的具体实现
我们可以在继承StopWatch
类后重写stop
方法,在调用super.stop()
后,进行耗时的日志打印。但这样还是每次都需要手动调用stop()
方法。
有没有一种办法可以让我们不在业务代码中主动调用stop
方法呢?
我们可以利用JDK7
的try-with-resources
特性:在try
后面可以创建一个实现了java.lang.AutoCloseable
接口的对象,该对象作用于整个try
语句块中,当try
语句块中的逻辑执行完毕后会自动回调java.lang.AutoCloseable#close()
方法。
来看下对StopWatch
增强的具体实现:
1 | package com.sunchaser.sparrow.springboot.utils; |
增强后,我们的使用方式如下:
1 | private static void testStopWatchWrapper() { |
运行后输出日志如下:
1 | 03:41:58.165 [main] INFO com.sunchaser.sparrow.springboot.utils.StopWatchWrapper - test-watch-wrapper-执行耗时101ms |
可看到已按照预期回调了org.springframework.util.StopWatch#stop()
方法并打印了日志。
-------------有过牵挂了无牵挂-------------
欢迎关注微信公众号【打工这件小事】~
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 打工这件小事!
评论