使用动态代理记录方法执行的时间

在大型系统中,我们经常需要监视我们系统执行的性能状况,当出现性能问题时,我们要 能够迅速地找到瓶颈在什么地方。在程序的层面上来说,就是看哪个方法执行所消耗的时间 很长。

使用动态代理可以非常方便的记录方法执行的时间,比如,下面的截图,就是 ESBasic.Emit.Aop.Interceptors.MethodTimeInterceptor截获器记录的片段:

2009-4-17  18:50:12:TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗 时:390ms
2009-4-17 18:50:16:TY.Web.MemberInterface.IMemberBL.GetOne方法耗时 :106ms
2009-4-17 18:50:23:TY.Web.MemberInterface.IMemberBL.GetOne方法耗 时:105ms
2009-4-17 18:50:23:TY.Web.MemberInterface.IMemberBL.GetOne方法耗时 :105ms
2009-4-17  18:50:24:TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗 时:386ms
2009-4-17  18:50:30:TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗 时:387ms
2009-4-17  18:50:35:TY.Web.AgentInterface.IGameRecordDetailBL.GetPaginationData方法耗 时:377ms
2009-4-17 18:50:43:TY.Web.MemberInterface.IMemberBL.GetOne方法耗时 :105ms
2009-4-17  18:51:14:TY.Web.MemberInterface.IGameBenefitBL.GetMemberBenefitData方法耗 时:714ms

在我们常见的三层架构中,我们可能需要记录UI层调用BL层的每个方法所执行的时间,那 我们可以这样做。假设BL提供给UI访问的接口为IBL(可能有多个,如IBL1,IBL2, IBL3,......),BL通过Remoting的方式发布它的服务。

//BL层给UI层调用的接口
public interface IBL
{
}
//BL的实现
public class BLObject : IBL
{
}

那么,我们让BL不直接发布实现了IBL接口的对象(BLObject),而是发布拦截了这个对 象的动态代理,就像这样:

IMethodTimeLogger logger = new MethodTimeLogger(new  FileAgileLogger("TimeLogger.txt") ,100);
IBL blObject = ...; //BLObject 的实例
IBL blObjectProxy =  DynamicProxyFactory.CreateAopProxy<IBL>(blObject, null, new  MethodTimeInterceptor(logger));

blObjectProxy即是拦截了blObject调用的动态代理,它和BLObject 一样实现了IBL接口 ,并且将所有的调用转发给blObject,而且记录了blObject每个方法执行的时间。我们可以 将blObjectProxy对象发布为Remoting,这样就可以记录下BL每个方法的执行时间了。

在上面的例子中,IMethodTimeLogger 接口是用于记录时间的记录器接口,我们可以将 时间记录到日志文件,当然也可以记录到数据库或其他地方,你只要实现IMethodTimeLogger  接口就可以了。这里我们将时间记录到TimeLogger.txt文件,注意,MethodTimeLogger  的第二个参数100,表示只记录那些执行时间超过100ms的方法调用,因为如果要记录所有的 方法调用的话,在大型系统中日志可能会在很短的时间内就变得非常的庞大,这样反而不利 于日志查看。

再回到上面的日志片段,我们看到,日志记录了BL接口中具体方法的调用时间,执行所消 耗的时长,这样我们就可以很方便的找到性能的瓶颈是在那个方法的调用上产生的了。

上述例子中所用到的类都位于ESBasic.dll中,你可以下载进行试验。ESBasic中的动态代 理技术是基于Emit实现的,有兴趣的话你可以使用Reflector来查看其实现原理。

本文附件

时间: 2024-10-30 11:47:28

使用动态代理记录方法执行的时间的相关文章

代理模式之Java动态代理实现方法_java

今天一个偶然的机会我突然想看看JDK的动态代理,因为以前也知道一点,而且只是简单的想测试一下使用,使用很快里就写好了这么几个接口和类:接口类:UserService.java 复制代码 代码如下: package com.yixi.proxy;public interface UserService {    public int save() ;    public void update(int id);} 实现类:UserServiceImpl.java 复制代码 代码如下: packag

【设计模式】动态代理Proxy_01

大家都知道设计模式中一个比较难理解的模式--动态代理模式,下面我们来通过一步一步完善一个工程来学习动态代理. 首先我们创建一个JavaProject,名字为"ProxyTest". 创建一个类Tank.java,是一个坦克类,然后我们创建一个接口Moveable.java Moveable.java: package cn.edu.hpu.proxy; public interface Moveable { void move(); } Tank类实现Moveable接口 Tank.j

Java 反射之动态代理

利用Java反射机制你可以在运行期动态的创建接口的实现.java.lang.reflect.Proxy类就可以实现这一功能.这个类的名字(译者注:Proxy意思为代理)就是为什么把动态接口实现叫做动态代理.动态的代理的用途十分广泛,比如数据库连接和事物管理(transaction management)还有单元测试时用到的动态mock对象以及AOP中的方法拦截功能等等都使用到了动态代理. 创建代理你可以通过使用Proxy.newProxyInstance()方法创建动态代理.newProxyIn

Java Reflection(十一):动态代理

原文地址作者: Jakob Jenkov 译者:叶文海(yewenhai@gmail.com) 内容索引创建代理InvocationHandler接口 常见用例 数据库连接以及事物管理 单元测试中的动态Mock对象 自定义工厂与依赖注入(DI)容器之间的适配器 类似AOP的方法拦截器 利用Java反射机制你可以在运行期动态的创建接口的实现.java.lang.reflect.Proxy类就可以实现这一功能.这个类的名字(译者注:Proxy意思为代理)就是为什么把动态接口实现叫做动态代理.动态的代

跟屌丝大哥学习设计模式---代理模式之动态代理

动态代理 java中动态代理机制的引入使得代理模式的思想更加完善与进步,它允许动态的创建代理并支持对动态的对所代理的方法进行调用.Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:  (1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args).在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上

设计模式之动态代理(dynamic proxy)

1 动态代理与静态代理 我们从上一篇设计模式之代理模式一文中已经知道,在代理模式中代理对象和被代理对象一般实现相同的接口,调用者与代理对象进行交互.代理的存在对于调用者来说是透明的,调用者看到的只是接口.这就是传统的代理模式静态代理的特点. 那么传统的静态代理模式有什么问题呢?如果需要代理的类只有一个,那么静态代理没什么问题,如果有很多类需要代理呢,用静态代理的话就需要为每一个类创建一个代理类,显然这么做太过繁琐也容易出错.为此,JDK 5引入的动态代理机制,允许开发人员在运行时刻动态的创建出代

动态代理

1.什么是动态代理? 动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可. 平常实现一个接口需要写一个具体的实现类,而动态代理技术能够在运行期间动态的生成实现指定接口的实现类对象,底层使用的反射原理.在框架中经常使用,例如:Struts1.Struts2.Spring和Hibernate等等.学习动态代理可以更好的理解框架内部的原理. 2.主要技术 创建动态代理的方法: Use

动态代理解释-JDK,CGLIB,JAVASSIST,ASM

动态代理是指在运行时,动态生成代理类.代理类的字节码将在运行时生成并载入当前的ClassLoader.          生成动态代理类的方法很多,如JDK自带的动态代理.CGLIB.Javassist或者ASM库.           JDK动态代理使用简单,它内置在JDK中,因此不需要引入第三方Jar包,但相对功能比较弱.CGLIB和Javassist都是高级的字节码生成库,总体性能比JDK自带的动态代理好,而且功能十分强大.ASM是低级的字节码生成工具,使用ASM已经近乎在于使用Javab

pring 动态代理-Quartz怎么能不实现job接口而自己指定要执行的方法(就像sping中的那样)

问题描述 Quartz怎么能不实现job接口而自己指定要执行的方法(就像sping中的那样) 如题 这次代码中没用到spring 因此以前在spring中用下列方式实现 class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> run 的如今不能用了 怎么才能简单的做使得quartz直接调用自己指定的方法而不是 必须要继承Job实现execute()方法 解决方案 写一个代理