并不是很想写这个系列,因为这个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. 常见CSS与HTML使用误区

       误区一.多div症 <div class="nav"> <ul> <li><a href="/home/"> ...

  2. Hive安装配置指北(含Hive Metastore详解)

    个人主页: http://www.linbingdong.com 本文介绍Hive安装配置的整个过程,包括MySQL.Hive及Metastore的安装配置,并分析了Metastore三种配置方式的区 ...

  3. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  4. [C#] C# 知识回顾 - 序列化

    C# 知识回顾 -  序列化 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902005.html 目录 序列化的含义 通过序列化保存对象数据 众 ...

  5. [原]Paste.deploy 与 WSGI, keystone 小记

    Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...

  6. 安装angular-cli

    最近在学习angular2,并尝试用这个框架来做公司的一个新项目. 终于要开始开发了,等了1个多月. 因为第一次用这个新框架做项目,不太熟悉,就找了angular-cli这个脚手架来搭建项目. 安装了 ...

  7. 【Java大系】Java快速教程

    感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品.James Gosling领 ...

  8. Maven搭建SpringMVC+Hibernate项目详解 【转】

    前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...

  9. 太多选择——企业如何选择合适的BI工具?

    在没认清现状前,企业当然不能一言不合就上BI. BI不同于一般的企业管理软件,不能简单归类为类似用于提高管理的ERP和WMS,或用于提高企业效率的OA.BPM.BI的本质应该是通过展现数据,用于加强企 ...

  10. 统计iOS项目的总代码行数的方法

    打开终端, 用cd命令 定位到工程所在的目录,然后调用以下命名即可把每个源代码文件行数及总数统计出来: find . "(" -name "*.m" -or - ...