Spring系列(3/1)---交互的一种尝试
来源:互联网 发布:基于mac的acl 编辑:程序博客网 时间:2024/06/08 06:56
前一篇,我们知道可以利用委托和代理来实现为目标类增加额外责任,这里我们先用一个简单的例子说明如何去实现.
//目标类,有3个公共方法,但由于非虚方法无法继承,所以能够切入的只有2个公共虚方法。虽然从生产代理的角度来讲,非虚公共方法也可以截获,
//但要求代理类重写该方法,而一旦重写,根据方法的调用规则,在用目标类型调用这个方法时,其实是调不到代理类中的这个方法的,所以就没有机会截获和监视。
public class AClass
{
public virtual void Save()
{
Console.WriteLine("sadfdsaf");
}
public virtual string GetName(int i)
{
return "tina" + i.ToString();
}
public void DoSomething()
{
Console.WriteLine("AClass DoSomething()");
}
}
/// <summary>
/// 交互委托
/// </summary>
/// <param name="Target">目标类</param>
/// <param name="Sender">代理类</param>
/// <returns>执行结果</returns>
public delegate bool InteractorDelegate(object Target,object Sender);
/// <summary>
/// 代理类,从AClass继承.
/// </summary>
public class ProxyAClass1 : AClass
{
private AClass _target;
private List<IMethodInterceptor> _adviceList = null;
public event InteractorDelegate InteractAtA;
public event InteractorDelegate InteractAtB1;
public event InteractorDelegate InteractAtB2;
public event InteractorDelegate InteractAtC1;
public event InteractorDelegate InteractAtC2;
public event InteractorDelegate InteractAtD;
public event InteractorDelegate InteractAtE;
/// <summary>
/// 构造函数,需传入目标类实例.
/// </summary>
/// <param name="target"></param>
public ProxyAClass1(AClass target)
{
_target = target;
}
/// <summary>
/// 执行方法实例.这里只以一个方法做演示.
/// </summary>
public override void Save()
{
try
{
if (InteractAtA != null)
{
InteractAtA(_target, this);
}
if (InteractAtB1 != null)
{
if (InteractAtB1(_target, this) == true)
{
if (InteractAtB2 != null)
{
InteractAtB2(_target, this);
}
_target.Save();
if (InteractAtC1 != null)
{
InteractAtC1(_target, this);
}
}
}
if (InteractAtC2 != null)
{
InteractAtC2(_target, this);
}
}
catch
{
if (InteractAtD != null)
{
InteractAtD(_target, this);
}
}
finally
{
if (InteractAtE != null)
{
InteractAtE(_target, this);
}
}
}
}
//下面是用法
//测试类.
public class TestClass
{
public static void Test()
{
AClass A = new AClass();
AClass PA = new ProxyAClass1(A);
PA.InteractAtA += new InteractorDelegate(PA_InteractAtA);
PA.InteractAtB1 += new InteractorDelegate(PA_InteractAtB1);
//......
}
static bool PA_InteractAtB1(object Target, object Sender)
{
//do something
return true;
}
static bool PA_InteractAtA(object Target, object Sender)
{
//do something
return false;
}
}
一个简单的代理完成了,也可以进行交互,手工方式还可以。但这种方式存在两个问题:
1)采用事件,那么多个方法挂接时执行的顺序并不能保证,而且很难实现选票制
2)如果动态生成类采用这种方式,有一个非常大的问题,就是上面代码红色部分无法实现,因为代理类是动态生成的,写代码的时候是编译过不去的。
实例化代理类比较容易实现,但事件挂接比较没法,没法静态写。
那怎么办呢?下一篇我们就来改进,一点点的去完成动态代理的要求。
后记:因为非虚方法不能作为监视的方法,因此我前面的动态代码生成时可以把这些方法除掉。同时执行方法的方式也可以直接改成调用,不用采用反射方式。
- Spring系列(3/1)---交互的一种尝试
- Spring系列(3/1)---交互的一种尝试
- Spring系列(3/1)---交互的一种尝试
- Spring系列(3/2)---交互的改进
- Spring系列(3/2)---交互的改进
- Spring系列(3/2)---交互的改进
- 学J2EE的一种尝试
- 尝试一种新的生命状态
- 尝试一种新的带人方式
- 尝试一种新的生命状态
- 数据库访问类的一种尝试
- 尝试一种新的带人方式
- 扩展MapReduce架构的一种尝试
- 我的Spring初尝试
- Qt 3D的研究(九):尝试另外一种边缘检测方法
- 一种线程交互模型的实现
- 一种与服务器交互的方式
- protobuf 一种高效的接口交互数据格式
- 回顾:在生产环境中使用Haskell
- EasyUI 验证框使用方法
- 136. Single Number
- 自定义Toast
- ffmpeg处理RTMP流媒体的命令大全
- Spring系列(3/1)---交互的一种尝试
- PL/SQL开发常见SQL知识
- android小细节
- leetcode503 Next Greater Element II java
- Android跨应用Activity跳转
- caffe在prototxt文件加参数
- Spring系列(3/2)---交互的改进
- 求职旺季,你可能遇到的五大“惨案”
- 关于初始化列表的问题