LinFu Dynamic Proxy - LinFu 2.3, LinFu.DynamicProxy 1.031
实现的特性有:
1. AOP
2. Dynamic Proxy
3. Minxins
4. Duck Typing
5. Design by Contract
基本示例
public class SimpleSamepleEntity
{public SimpleSamepleEntity(){Console.WriteLine("create SimpleSamepleEntity");}public virtual string Name { get; set; }public virtual int Age { get; set; }public override string ToString(){return string.Format("{{ Name: \"{0}\", Age: {1} }}", this.Name, this.Age);}
}
public class SimpleSampleInterceptor : IInterceptor
{private SimpleSamepleEntity _target;public SimpleSampleInterceptor(SimpleSamepleEntity target){this._target = target;}public object Intercept(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);return info.TargetMethod.Invoke(this._target, info.Arguments);}
}
public class SimpleSampleWrapper : IInvokeWrapper
{private SimpleSamepleEntity _target;public SimpleSampleWrapper(SimpleSamepleEntity target){this._target = target;}public void BeforeInvoke(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);}public object DoInvoke(InvocationInfo info){return info.TargetMethod.Invoke(this._target, info.Arguments);}public void AfterInvoke(InvocationInfo info, object returnValue){Console.WriteLine("<<Intercepted " + info.TargetMethod.Name + ", result: " + (returnValue == null ? "null" : returnValue.ToString()));}
}
使用代码:
ProxyFactory factory = new ProxyFactory();
SimpleSamepleEntity entity = new SimpleSamepleEntity() { Name = "Richie", Age = 99 };
SimpleSampleInterceptor interceptor = new SimpleSampleInterceptor(entity);
SimpleSamepleEntity proxy1 = factory.CreateProxy<SimpleSamepleEntity>(interceptor);
Console.WriteLine(proxy1.Name);
Console.WriteLine(proxy1.ToString());
Console.WriteLine("==============================");
SimpleSampleWrapper wrapper = new SimpleSampleWrapper(entity);
SimpleSamepleEntity proxy2 = factory.CreateProxy<SimpleSamepleEntity>(wrapper);
Console.WriteLine(proxy2.Name);
Console.WriteLine(proxy2.ToString());
Console.ReadKey();
运行结果:
说明:
1. LinFu的Dynamic Proxy有2种方式实现拦截器,即上面示例的IInterceptor和IInvokeWrapper接口
2. 与Castle Dynamic Proxy的不同之处在于,LinFu的拦截器只负责拦截功能,他并不维护目标真实对象,所以表现出来的差异有:
a). 在拦截器接口中没有类似Castle的invocation.Proceed类似的方法,因为LinFu根本不知道目标真实对象在哪里。上面示例中我们在IInterceptor和IInvokeWrapper构造器中传入了目标对象,在拦截器接口方法中在_target对象上调用目标方法
b). Castle在创建class proxy的时候,如果没有提供target,Castle会自己创建一个目标实体对象。而LinFu将interceptor与目标对象分离,所以在创建代理对象的时候不会创建目标对象
c). 可以这样理解,LinFu的代理对象与Castle的interface proxy without target的行为基本一致。如果使用者也不处理target,则代理对象仅仅是一个拦截器,比Castle的class proxy要简洁
3. LinFu不像Castle,将proxy分为class proxy、interface proxy等类型,在LinFu中这些概念对使用者是透明的,但这里面也有些方面值得注意:
a). 如果创建的是class proxy,则只能对virtual的方法进行拦截;如果创建的是interface proxy,非virtual的方法也可以实现拦截,这一点与Castle是一致的
b). 如果创建的是interface proxy,即使目标对象override了ToString等方法,LinFu也无法通过info.TargetMethod.Invoke调用到目标对象的ToString方法
4. 拦截机制上的差异
上面示例中,SimpleSamepleEntity的ToString方法中还调用了this.Name、this.Age,在Castle中这2个调用可以被拦截到,但LinFu中只能拦截到ToString方法
LinFu的代理对象都实现了IProxy接口,可以通过IProxy接口动态改变拦截器。比如上面的例子中,再实现一个拦截器:
public class AnotherInterceptor : IInterceptor
{public object Intercept(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);return null;}
}
ProxyFactory factory = new ProxyFactory();
SimpleSamepleEntity entity = new SimpleSamepleEntity() { Name = "Richie", Age = 99 };
SimpleSampleInterceptor interceptor = new SimpleSampleInterceptor(entity);
SimpleSamepleEntity proxy = factory.CreateProxy<SimpleSamepleEntity>(interceptor);
Console.WriteLine("name: " + proxy.Name);
Console.WriteLine("entity: "+proxy.ToString());
AnotherInterceptor interceptor2 = new AnotherInterceptor();
(proxy as IProxy).Interceptor = interceptor2;
Console.WriteLine("name: " + proxy.Name);
Console.WriteLine("entity: " + proxy.ToString());
Console.ReadKey();
性能对比:
下图是作者做的一个与Castle DP的性能对比测试,都禁用掉了缓存,创建不同类型的代理对象。横轴是创建代理对象的个数,纵轴是所花的时间
准备看一下LinFu的DynamicObject、IoC,但这2个功能只在1.0的版本中才有,在后来新的LinFu.Core.dll、LinFu.DynamicProxy.dll程序集的基础上没法使用。github中最新的代码里面也没有DynamicObject这个对象,作者还在修改
参考:
Introducing the LinFu Framework, Part I - LinFu.DynamicProxy: A Lightweight Proxy Generator
Introducing the LinFu Framework, Part II: LinFu.DynamicObject – Adding Dynamic Language Features to Statically Typed Languages
Introducing the LinFu Framework, Part III: LinFu.Delegates-Lambda Arguments & Universal Event Handling
Introducing the LinFu Framework, Part IV: Simple.IOC – The Five Minute Inversion of Control Container
Introducing the LinFu, Part V: LinFu.DesignByContract2 – Adding Transparent Design by Contract Features to Any .NET Language
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language
LinFu Dynamic Proxy - LinFu 2.3, LinFu.DynamicProxy 1.031相关推荐
- The bean ‘xxx‘ could not be injected as a ‘xxx‘ because it is a JDK dynamic proxy that implements:
The bean 'xxx' could not be injected as a 'xxx' because it is a JDK dynamic proxy that implements: 问 ...
- The bean ‘Xxx‘ could not be injected as a ‘Xxx‘ because it is a JDK dynamic proxy that implements:x
完成错误信息如下: *************************** APPLICATION FAILED TO START ***************************Descrip ...
- The bean 'llWebSocketHandler' could not be injected because it is a JDK dynamic proxy that implemen
摘要:在做Spring Boot.WebSockets整合的时候,出现了bean注入失败的问题,错误异常如下: 一:异常信息: 2018-08-10 11:44:50.072 WARN 20296 - ...
- Spring aop(Aspectj)对dynamic proxy的类是无能为力的
spring的aop是基于代理的,aspectj的aop的织入方式有以下几种: compile-time weaving, post-compile time weaving, and load-ti ...
- because it is a JDK dynamic proxy that implements问题 看这一篇就够了
一.背景 开发中常见这个错误: The bean 'xxxService' could not be injected as a'com.xxxx.xxx.xxxService' because it ...
- The bean 'xxx' could not be injected as a 'xxx'because it is a JDK dynamic proxy that implements
启动springboot项目的时候示以下错误 1 Error starting ApplicationContext. To display the conditions report re-run ...
- The bean ‘xxImpl‘ could not be injected as a ‘xxx‘ because it is a JDK dynamic proxy that implements
项目启动报错:The bean 'xxxServiceImpl' could not be injected as a 'com.xxx.service.impl.xxxServiceImpl' be ...
- The bean ‘xxx‘ could not be injected as a ‘xxx‘because it is a JDK dynamic proxy that implements错误解决
1.解决方法:使用@Autowired 2.@autowired和@resource注解的区别 区别: 1.@Autowired注解由Spring提供,只按照byType注入:@resource注解由 ...
- The bean ‘XXX‘ could not be injected because it is a JDK dynamic proxy
1.看了网上的方法说先把mybatis-plus依赖注释掉,没有反应. 2.通过将Controller文件都注释掉,发现@Resource出问题了,有两个对象名相同 3.修改了其中一个名,果然解决
最新文章
- 一台服务器上起2个mysql服务
- 为什么你应该停止阅读新闻?
- 使用idea创建gradle的springboot工程
- datagrip替换字_DataGrip使用进阶-导航及搜索(一)
- 二叉树经典题之根据二叉树创建字符串(二叉树的括号表示法)
- 基于JAVA+Spring+MYSQL的婚纱摄影网站
- matlab 快速傅里叶变换函数(fft)编写
- python电子书合集
- PS2015下载PSCC2015安装教程
- No ip domain-lookup和Logging synchronous和Exec-timeout 0 0
- Cesium开发环境搭建的几种方法总结
- 魏巍专访丨合作半年拓客100+,他是如何做到的?
- linux Guest账户下如何更新默认的python版本
- 基于深度学习的语义分割
- 小波神经网络(时间序列预测)
- Python - names模块解析(海量英文名)
- python 实现zigzag排列
- Apache基于域名、端口、IP的虚拟主机配置(Centos 6.5)
- 辗转相除法+更相减损法求最大公约数
- 椭圆曲线加密和签名算法