利用AOP寫2PC框架(一),aop寫2pc框架
並不是很想寫這個系列,因為這個2pc單獨寫一個小架構有點雞肋。不過也不知道寫什麼了,先寫了再說吧。
整個流程如下圖:

關於AOP系列的文章很多,我這裡也再重復造一下輪子。
首先,我們定義了一個IAopProxy,用於給AopProxyFactory用來創建Proxy實例的接口,代碼如下:

![]()
public interface IAopProxy
{
AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);
}
View Code
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 > 0)
{
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);
}
View Code
同時,我們定義了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();
}
}
View Code
可以看到在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);
}
}
}
View Code
那道這裡Aop的基礎類就搭建完畢了,具體的攔截後,要做什麼,則需要去繼承於我們的抽象類AopProxyBase,然後復寫After和Before去做一些攔截,記錄的工作。
利用Spring的AOP實現權限控制
用java動態代理就可以搞定了
建議好好看看代理模式
什是AOP編程?
面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發中的一個熱點,也是Spring框架中的一個重要內容。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。 AOP是OOP的延續,是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。
可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。