利用AOP写2PC框架(一)
并不是很想写这个系列,因为这个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框架(一)的更多相关文章
- 利用AOP写2PC框架(二)
AOP的底层已经封装好了以后,我们就要开始针对应用层写具体的业务逻辑了. 也就是说我们需要有个类继承于AopProxyBase,并且重写其After,Bofore以达到我们的拦截记录的功能.代码如下: ...
- 关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能
Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方. Quar ...
- SpringBoot31 整合SpringJDBC、整合MyBatis、利用AOP实现多数据源
一.整合SpringJDBC 1 JDBC JDBC(Java Data Base Connectivity,Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数 ...
- 利用AOP切面打印项目中每个接口的运行情况
1.前言 AOP切面技术,大家应该都听知道,Spring框架的主要功能之一. AOP切面的用途很广,其中一个常见的用途就是打印接口方法的运行日志和运行时间. 日志对于一个项目很是重要,不仅有助于调错, ...
- .NET Core的日志[5]:利用TraceSource写日志
从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...
- 利用AOP与ToStringBuilder简化日志记录
刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla...... IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到ao ...
- Python基础篇【第3篇】: Python异常处理、反射、动态导入、利用反射的web框架
异常处理 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当P ...
- 利用多写Redis实现分布式锁原理与实现分析(转)
利用多写Redis实现分布式锁原理与实现分析 一.关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到. 我举二个例子:场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能 ...
- 利用TraceSource写日志
利用TraceSource写日志 从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试 ...
随机推荐
- Apache Ignite之集群应用测试
集群发现机制 在Ignite中的集群号称是无中心的,而且支持命令行启动和嵌入应用启动,所以按理说很简单.而且集群有自动发现机制感觉对于懒人开发来说太好了,抱着试一试的心态测试一下吧. 在Apache ...
- dotNET跨平台相关文档整理
一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- HTML 事件(二) 事件的注册与注销
本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...
- Laravel 5.x 请求的生命周期(附源码)
Laravel最早接触是刚开始实习的时候,那时通过网上的学习资料很快便上手,开发模块接口.后来没有什么深入和总结,但是当我刚开始学Laravel的时候,我对Laravel最大的认识就是,框架除了路由. ...
- 【初学python】使用python调用monkey测试
目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...
- OpenCV模板匹配算法详解
1 理论介绍 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标.OpenCV ...
- spring源码分析之<context:property-placeholder/>和<property-override/>
在一个spring xml配置文件中,NamespaceHandler是DefaultBeanDefinitionDocumentReader用来处理自定义命名空间的基础接口.其层次结构如下: < ...
- Openfiler配置RAC共享存储
将 Openfiler 用作 iSCSI 存储服务器,主要操作步骤如下: 1.设置 iSCSI 服务 2.配置网络访问 3.指定物理存储器并对其分区 4.创建新的卷组 5.创建所有逻辑卷 6.为每个逻 ...
- springmvc 多数据源 SSM java redis shiro ehcache 头像裁剪
获取下载地址 QQ 313596790 A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:31359679 ...