`

java代码中动态添加程序执行时间日志

    博客分类:
  • java
 
阅读更多

在写java代码的过程中经常会遇到需要打印一个方法的执行时间,如果在代码中直接写开始和结束时间,然后计算运行时间,这样感觉不太好,代码的耦合性太高,可以通过java的动态代理或者cglib 加上annotation(标注)来实现。
1.通过cglib代理打印当前方法的执行时间.
代码如下:

代理类:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
* User: weichun.zhan
* Date: 12-10-25
* Time: 下午3:09
*/
public class ServiceProxy implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Logger logger = LoggerFactory.getLogger(method.getDeclaringClass().getName());
        Object result = null;

        MethodRunTimeLog methodRunTimeLog = method.getAnnotation(MethodRunTimeLog.class);
        if (methodRunTimeLog !=null && methodRunTimeLog.debug()) {
            long start = System.currentTimeMillis();
            result = methodProxy.invokeSuper(o, objects); //因为cglib是通过继承类来实现代理,so需调用invokesuper
            long end = System.currentTimeMillis();
            logger.info("Excute  [{}] method took time [{}]ms.", method.getName(), (end - start));

        } else {
            result = methodProxy.invokeSuper(o, objects);
        }
        return result;
    }

    public Object createProxy(Class targetClass) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallback(new ServiceProxy());
        return enhancer.create();
    }
}
 

调用类:
ServiceProxy test = new ServiceProxy();
MovieInfoServiceServiceImpl proxyTarget = (MovieInfoServiceServiceImpl)test.createProxy(MovieInfoServiceServiceImpl.class);
 


2.当然也可以通过jdk的动态代理来做,代码如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* User: weichun.zhan
* Date: 12-10-25
* Time: 下午6:03
*/
public class MovieInfoServiceProxy implements InvocationHandler {

    private MovieInfoService impl;

    public MovieInfoServiceProxy(MovieInfoService impl){
        this.impl = impl;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Logger logger = LoggerFactory.getLogger(method.getDeclaringClass().getName());

        Object result = null;
       //获取调用方法的method对象,不能直接调用method,不知为什么还没仔细研究
        MethodRunTimeLog methodRunTimeLog = impl.getClass().getMethod(method.getName(),method.getParameterTypes()).getAnnotation(MethodRunTimeLog.class);
        if (methodRunTimeLog !=null && methodRunTimeLog.debug()) {
            long start = System.currentTimeMillis();
            result = method.invoke(impl, args);
            long end = System.currentTimeMillis();
            logger.info("Excute  [{}] method took time [{}]ms.", method.getName(), (end - start));

        } else {
            result = method.invoke(impl, args);
        }
        return result;
    }
}
 


调用代码:
 MovieInfoService proxyTarget = (MovieInfoService) Proxy.newProxyInstance(MovieInfoService.class.getClassLoader(),
                MovieInfoServiceImpl.class.getInterfaces(),new MovieInfoServiceProxy(new MovieInfoServiceImpl()));
        return proxyTarget;
 

标注类:

import java.lang.annotation.*;

/**
 * User: weichun.zhan
 * Date: 12-10-25
 * Time: 下午4:09
 */

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodRunTimeLog {

    boolean debug() default false;

}

 ServiceImpl:

 

@MethodRunTimeLog(debug = true)
    public List<MovieInfo> queryMovieInfos(Collection<String> cids) throws SQLException {
  //具体的实现省略。。。。
}

 

 

 

 

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java动态日志注入工具anylog.zip

    anylog 为开发人员提供一个易于使用的平台,帮助开发人员在正在运行的系统中随时加入自己想要的日志,而免于修改代码和重启。 使用场景举例  1、一些同学在写代码时,把异常吃掉了,使得问题难以查找,可以...

    Java微信小程序商城系统源码-.zip

    定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 系统接口:根据业务代码自动生成相。能 小程序用户管理 商

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    JAVA_API1.6文档(中文)

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Java聊天室程序(源代码)

    接收用户的聊天信息是由多线程技术实现的,因为客户端必须时时关注更新服务器上是否有最新消息,在本程序中设定的是3秒刷新服务器一次,如果间隔时间太短将会增加客户端与服务器端的通信负担,而间隔时间长就会让人...

    Java聊天室程序源码(毕业设计)

    接收用户的聊天信息是由多线程技术实现的,因为客户端必须时时关注更新服务器上是否有最新消息,在本程序中设定的是3秒刷新服务器一次,如果间隔时间太短将会增加客户端与服务器端的通信负担,而间隔时间长就会让人...

    java开源包10

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java jdk实列宝典 光盘源代码

    applications和applet,applications可以在控制台直接运行,与其他高级编程语言没有太大区别,而java的特色在于它具有编制小应用程序的功能,applet可以在internet上传输并在兼容java的web浏览器中运行的程序;...

    Java 使用javaCV、ffmpeg拉流H265 RTSP转推H264 RTMP可获取流访问人数(源代码)

    3、运行程序前需安装以上插件并在application.yml中配置。 4、本程序的功能为: 1)、拉取RTSP流转推RTMP,支持H265转H264。 2)、可选择使用javaCV推流、ffmpeg推流两种方式。 3)、javaCV仅支持拉去或推送H264...

    Java 1.6 API 中文 New

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包6

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包9

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    JavaAPI1.6中文chm文档 part1

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

    java开源包4

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Java 选修课程系统源代码,Eclipse+Mysql开发

    Java 选修课程管理系统,广东石油化工学院计算机07-1班 Logic 陈罗志原创程序,使用Eclipse+Mysql开发,代码中预设的Mysql数据库用户名为root,密码为admin,运行程序,测试用户用户名chenluozhi 密码chenluozhi ...

Global site tag (gtag.js) - Google Analytics