并不是很想写这个系列,因为这个2pc单独写一个小架构有点鸡肋。不过也不知道写什么了,先写了再说吧。

整个流程如下图:

关于AOP系列的文章很多,我这里也再重复造一下轮子。

首先,我们定义了一个IAopProxy,用于给AopProxyFactory用来创建Proxy实例的接口,代码如下:

    public interface IAopProxy
{
AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);
}

AOP截获最重要的就是RealProxy类了,我们写一个AopProxyBase抽象类,继承于RealProxy,代码如下:

public abstract class AopProxyBase : RealProxy
{
private readonly MarshalByRefObject target; //默认透明代理
public AopProxyBase(MarshalByRefObject obj, Type type)
: base(type)
{
this.target = obj;
} public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage call = (IMethodCallMessage)msg; bool isIntercept = false; var attrs = call.MethodBase.GetCustomAttributes(typeof(AopMethodAttribute), false) as AopMethodAttribute[]; //如果标记了AopMethodAttribute的,才记录。
if (attrs.Length > )
{
isIntercept = true;
} if (isIntercept)
{
this.Before(msg, attrs);
} //如果触发的是构造函数,此时target的构建还未开始
IConstructionCallMessage ctor = call as IConstructionCallMessage;
if (ctor != null)
{
//获取最底层的默认真实代理
RealProxy default_proxy = RemotingServices.GetRealProxy(this.target);
default_proxy.InitializeServerObject(ctor);
MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy(); return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);
} IMethodReturnMessage result_msg = RemotingServices.ExecuteMessage(this.target, call); if (isIntercept)
{
this.After(msg, result_msg, attrs);
} return result_msg;
} public abstract void Before(IMessage requestMsg, AopMethodAttribute[] attrs); public abstract void After(IMessage requestMsg, IMessage Respond, AopMethodAttribute[] attrs); }

同时,我们定义了AopAttribute : ProxyAttribute,代码如下:

[AttributeUsage(AttributeTargets.Class)]
public class AopAttribute : ProxyAttribute
{
IAopProxy proxy;
public AopAttribute(Type factoryType)
{
this.proxy = (IAopProxy)AopProxyFactory.CreateInstance(factoryType);
} public override MarshalByRefObject CreateInstance(Type serverType)
{
MarshalByRefObject target = base.CreateInstance(serverType); AopProxyBase rp = this.proxy.CreateAopProxyInstance(target, serverType); return (MarshalByRefObject)rp.GetTransparentProxy();
}
}

可以看到在AopAttribute的构造函数里面,有通过Factory去创建被拦截的Class的实例,避免每次都去创建,我加了一个Dictionary作为Cache,代码如下:

 public class AopProxyFactory
{
private static AopProxyCache _proxyCollection; private static readonly object _syncObject = new object();
static AopProxyFactory()
{
lock (_syncObject)
{
if (_proxyCollection == null)
{
_proxyCollection = new AopProxyCache();
}
}
} public static IAopProxy CreateInstance(Type type)
{
return _proxyCollection[type];
}
} public class AopProxyCache
{
public Dictionary<Type, IAopProxy> _proxys;
private static readonly object _syncObject = new object(); public AopProxyCache()
{
lock (this)
{
if (_proxys == null)
{
_proxys = new Dictionary<Type, IAopProxy>();
}
}
} public void Add(Type type, IAopProxy proxy)
{
if (_proxys == null) throw new ArgumentNullException("proxys is not init");
lock (_syncObject)
{
this._proxys[type] = proxy;
}
} public IAopProxy Get(Type type)
{
IAopProxy proxy;
if (this._proxys.ContainsKey(type))
{
proxy = this._proxys[type];
}
else
{
lock(_syncObject)
{
if (!this._proxys.ContainsKey(type))
{
proxy = (IAopProxy)Activator.CreateInstance(type);
this.Add(type, proxy);
}
else
{
proxy = this._proxys[type];
}
}
}
return proxy;
} public IAopProxy this[Type type]
{
get
{
return this.Get(type);
}
set
{
this.Add(type, value);
}
}
}

那道这里Aop的基础类就搭建完毕了,具体的拦截后,要做什么,则需要去继承于我们的抽象类AopProxyBase,然后复写After和Before去做一些拦截,记录的工作。

利用AOP写2PC框架(一)的更多相关文章

  1. 利用AOP写2PC框架(二)

    AOP的底层已经封装好了以后,我们就要开始针对应用层写具体的业务逻辑了. 也就是说我们需要有个类继承于AopProxyBase,并且重写其After,Bofore以达到我们的拦截记录的功能.代码如下: ...

  2. 关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能

    Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方. Quar ...

  3. SpringBoot31 整合SpringJDBC、整合MyBatis、利用AOP实现多数据源

    一.整合SpringJDBC 1  JDBC JDBC(Java Data Base Connectivity,Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数 ...

  4. 利用AOP切面打印项目中每个接口的运行情况

    1.前言 AOP切面技术,大家应该都听知道,Spring框架的主要功能之一. AOP切面的用途很广,其中一个常见的用途就是打印接口方法的运行日志和运行时间. 日志对于一个项目很是重要,不仅有助于调错, ...

  5. .NET Core的日志[5]:利用TraceSource写日志

    从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...

  6. 利用AOP与ToStringBuilder简化日志记录

    刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla...... IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到ao ...

  7. Python基础篇【第3篇】: Python异常处理、反射、动态导入、利用反射的web框架

    异常处理 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当P ...

  8. 利用多写Redis实现分布式锁原理与实现分析(转)

    利用多写Redis实现分布式锁原理与实现分析   一.关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到. 我举二个例子:场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能 ...

  9. 利用TraceSource写日志

    利用TraceSource写日志 从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试 ...

随机推荐

  1. 干货分享:SQLSERVER使用裸设备

    干货分享:SQLSERVER使用裸设备 这篇文章也适合ORACLE DBA和MYSQL DBA 阅读 裸设备适用于Linux和Windows 在ORACLE和MYSQL里也是支持裸设备的!! 介绍 大 ...

  2. Hello Web API系列教程——Web API与国际化

    软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...

  3. Jquery 搭配 css 使用,简单有效

    前几篇博客中讲了Jquery的基础和点击实际,下面来说一下和css搭配着来怎么做 还是和往常一样,举个例子 好几个方块,然后设置颜色 <!DOCTYPE html PUBLIC "-/ ...

  4. Android 获取系统相册中的所有图片

    Android 提供了API可获取到系统相册中的一些信息,主要还是通过ContentProvider 来获取想要的内容. 代码很简单,只要熟悉ContentProvider 就可以了. public ...

  5. 猖獗的假新闻:2017年1月1日起iOS的APP必须使用HTTPS

    一.假新闻如此猖獗 刚才一位老同事 打电话问:我们公司还是用的HTTP,马上就到2017年了,提交AppStore会被拒绝,怎么办? 公司里已经有很多人问过这个问题,回答一下: HTTP还是可以正常提 ...

  6. pt-ioprofile

    pt-ioprofile是用来观察特定进程的IO信息的. 该脚本是用shell写的,有两方面的作用: pt-ioprofile does two things: ) ) is not performe ...

  7. photoshop:无法完成请求 因为暂存盘已满

    今天photoshop打开一个问题,提醒:无法完成请求因为暂存盘已满 不用担心这个问题很好解决可能是你做的图比较大并不需要清理C盘空间 选择:编辑→首选项→暂存盘 设置第一暂存盘为D盘或E盘 总之 第 ...

  8. PC虚拟现实应用的性能分析与优化:从CPU角度切入

    如今,虚拟现实 (VR) 技术正日益受到欢迎,这主要得益于遵循摩尔定律的技术进步让这一全新体验在技术上成为可能.尽管虚拟现实能给用户带来身临其境般的超凡体验,但相比传统应用,其具有双目渲染.低延迟.高 ...

  9. Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器

    最近在业余时间玩玩树莓派,刚开始的时候在树莓派里写一些基于wiringPi库的C语言程序来控制树莓派的GPIO引脚,从而控制LED发光二极管的闪烁,后来觉得,是不是可以使用HTML5+jQuery等流 ...

  10. 如何从本地导入.nupkg文件

    买了本asp.net mvc4高级编程 里面的源码下载下来是.nupkg后缀的文件,不知道怎么引入到项目中, baidu无果,只好google,可怜我英语四级都难的人,不过所幸还是找到了方法: htt ...