使用AOP的方式监测方法执行耗时
2015-03-25 12:05
260 查看
在一些对系统中,往往可能需要对一些核心业务做相应的监测。如:记录调用参数,返回值,方法执行耗时等等。如果直接在方法的前后加入代码,如下:
这样有以下几点问题:
1.将业务逻辑和方法执行监测混在一起。
2.会有大量重复代码,哪怕你做了一层封装,也依然不够优雅。
由于有了以上的问题,我们会思考,如果可以将方法的调用过程抽象出来,在方法开始调用和方法调用结束时,植入代码,这样就可以很好的解决我们的问题。
.NET中,我们可以通过RealProxy来实现我们想要的功能。RealProxy(https://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.remoting.proxies.proxyattribute(v=vs.100).aspx)MSDN的定义。在Invoke方法中,可以拦截方法的执行,那么我们就可以在方法的执行前后做一些事情啦。
那么怎么更优雅的应用在方法上呢,我们可以用ProxyAttribute使用Attribute的方式。可以在对象初始化的时候(new关键字)创建相应的代理类。具体代码如下:
InjectProxy代码如下:
我在这里只记录了方法执行耗时,可以从call里拿到参数,从back里获取到返回值。
具体调用地方如下,注意类需要继承ContextBoundObject:
public int F(int a, string s) { var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"); var sw = Stopwatch.StartNew(); int ret = 1; long second = sw.ElapsedMilliseconds; var end = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"); log.Write(now, end, second, a, s, ret); }
这样有以下几点问题:
1.将业务逻辑和方法执行监测混在一起。
2.会有大量重复代码,哪怕你做了一层封装,也依然不够优雅。
由于有了以上的问题,我们会思考,如果可以将方法的调用过程抽象出来,在方法开始调用和方法调用结束时,植入代码,这样就可以很好的解决我们的问题。
.NET中,我们可以通过RealProxy来实现我们想要的功能。RealProxy(https://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.remoting.proxies.proxyattribute(v=vs.100).aspx)MSDN的定义。在Invoke方法中,可以拦截方法的执行,那么我们就可以在方法的执行前后做一些事情啦。
那么怎么更优雅的应用在方法上呢,我们可以用ProxyAttribute使用Attribute的方式。可以在对象初始化的时候(new关键字)创建相应的代理类。具体代码如下:
/// <summary> /// 标记要性能监测的类 /// </summary> [AttributeUsage(AttributeTargets.Class)] public class MonitorServiceAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { var instance = base.CreateInstance(serverType); var proxy = new InjectProxy(serverType, instance).GetTransparentProxy(); return proxy as MarshalByRefObject; } }
InjectProxy代码如下:
public override IMessage Invoke(IMessage msg) { var call = (IMethodCallMessage) msg; var ctr = call as IConstructionCallMessage; IMethodReturnMessage back; if (ctr != null) { RealProxy defaultProxy = RemotingServices.GetRealProxy(_instance); defaultProxy.InitializeServerObject(ctr); back = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctr, (MarshalByRefObject) GetTransparentProxy()); } else { var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"); var sw = Stopwatch.StartNew(); back = RemotingServices.ExecuteMessage(_instance, call); long second = sw.ElapsedMilliseconds; var attr = MethodAttributeCache.GetAttribute<MonitorMethodAttribute>(_instance.GetType().TypeHandle, call.MethodBase); if (attr != null) { attr.Value = second.ToString(); attr.ExecuteTime = now; Queue.Enqueue(Mapper(attr)); } } return back; }
我在这里只记录了方法执行耗时,可以从call里拿到参数,从back里获取到返回值。
具体调用地方如下,注意类需要继承ContextBoundObject:
internal class Program { private static void Main(string[] args) { var t = new Test(); t.F(1,"aaa"); } } [MonitorService] internal class Test : ContextBoundObject { [MonitorMethod("A")] public int F(int a,string s) { return 333; } }
相关文章推荐
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
- SpringAOP注解方式监控方法执行情况
- 【HAVENT原创】使用 Spring Boot 的 AOP 拦截器终止方法执行
- js replace 全局替换 以表单的方式提交参数 判断是否为ie浏览器 将jquery.qqFace.js表情转换成微信的字符码 手机端省市区联动 新字体引用本地运行可以获得,放到服务器上报404 C#提取html中的汉字 MVC几种找不到资源的解决方式 使用Windows服务定时去执行一个方法的三种方式
- Spring aop 注解方式怎么获得执行了目标的某个方法?
- 使用ASM4.0实现AOP的功能,监控每个方法的执行时间
- C#代码执行耗时计算,此处是监测的mvc控制器方法
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
- 使用Spring3.0的AOP结合log4j实现接口方法执行时间记录
- Case:接口实现类的方法上使用AspectJ方式实现aop的异常问题
- Spring aop 注解方式怎么获得执行了目标的某个方法?
- 使用ASM4.0实现AOP的功能,监控每个方法的执行时间
- 使用GCD的方式来下载图片(耗时操作: 子线程执行)
- Spring AOP 使用注解的方式实现用户日志的两种方法
- 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。
- 使用Windows服务定时去执行一个方法的三种方式
- C#代码执行耗时计算,此处是监测的mvc控制器方法
- spring boot使用 aop 处理方法的执行顺序
- cublas中执行矩阵乘法运算的函数 首先要注意的是cublas使用的是以列为主的存储方式,和c/c++中的以行为主的方式是不一样的。处理方法可参考下面的注释代码
- 使用Spring的AOP实现接口方法执行时间记录