Spring.NET学习笔记12——面向切面编程(基础篇) Level 300
AOP即面向切面編程(Aspect Oriented Programming的縮寫),是OOP(面向對象編程)的一種延續形式。是通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術,它從一個不同于OOP的角度來看待程序的結構:OOP將應用程序分解為一系列表現為繼承關系的對象;AOP 則把程序分解為一系列方面(aspects)或者關注點(concerns)。AOP將諸如事務管理等本來橫向分布在多個對象中的關注點進行了模塊化處理(這些關注點也常稱為橫切(crosscutting)關注點)。在Spring.NET中提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。
下面我舉個例子來說明這一切:
場景:業務類CompanyManager在調用Save方法的時候需要調用SecurityManager類判斷權限是否足夠(圖1)。
圖1
?
準備條件:
????public?class?CompanyDao????{
????????public?void?Save()
????????{
????????????Console.WriteLine("保存數據");
????????}
????}
?
????public?interface?ICompanyManager????{
????????string?UserName?{?get;?set;?}
????????void?Save();
????}
?
????public?interface?ISecurityManager????{
????????bool?IsPass(string?userName);
????}
?
SecurityManager????public?class?SecurityManager?:?ISecurityManager
????{
????????/**////?<summary>
????????///?判斷權限
????????///?</summary>
????????///?<param?name="userName"></param>
????????///?<returns></returns>
????????public?bool?IsPass(string?userName)
????????{
????????????return?userName?==?"admin";
????????}
????}
?
第一種實現方式,我們通常會這樣做:直接在CompanyManager類中調用ISecurityManager接口的IsPass方法判斷權限。
?
SimpleCompanyManagerpublic?class?SimpleCompanyManager?:?ICompanyManager
????{
????????可通過外部注入的屬性#region?可通過外部注入的屬性
????????public?string?UserName?{?get;?set;?}
????????public?CompanyDao?Dao?{?get;?set;?}
????????#endregion
????????public?void?Save()
????????{
????????????//判斷權限
????????????ISecurityManager?security?=?new?SecurityManager();
????????????if?(security.IsPass(UserName))
????????????{
????????????????//執行業務方法
????????????????//.
????????????????//調用DAO層方法
????????????????Dao.Save();
????????????}
????????????else
????????????{
????????????????//執行其它業務方法
????????????????Console.WriteLine("您沒有該權限");
????????????}
????????}
????}
?
這樣CompanyManager類與ISecurityManager或SecurityManager會發生業務性耦合。聰明的朋友會發現在GOF(設計模式)中有一種模式(代理模式)可以解除這種耦合。
第二種實現方式,代理模式(Proxy Pattern):什么是代理模式?是給某一個對象提供一個代理對象,并由代理對象控制對源對象的引用。代理就是一個人或一個機構代表另一個人或者一個機構采取行動。某些情況下,客戶不想或者不能夠直接引用一個對象,代理對象可以在客戶和目標對象直接起到中介的作用。客戶端分辨不出代理主題對象與真實主題對象。代理模式可以并不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創建被代理對象,被代理對象必須有系統的其他角色代為創建并傳入(圖2)。
圖2
????public?class?CompanyManager?:?ICompanyManager
????{
????????可通過外部注入的屬性#region?可通過外部注入的屬性
????????public?string?UserName?{?get;?set;?}
????????public?CompanyDao?Dao?{?get;?set;?}
????????#endregion
????????public?void?Save()
????????{
????????????//執行業務方法
????????????//.
????????????//調用DAO層方法
????????????Dao.Save();
????????}
????}
?
CompanyProxyManager????public?class?CompanyProxyManager?:?ICompanyManager
????{
????????public?string?UserName?{?get;?set;?}
????????private?ICompanyManager?target?=?new?CompanyManager();
????????public?void?Save()
????????{
????????????//判斷權限
????????????ISecurityManager?security?=?new?SecurityManager();
????????????if?(security.IsPass(UserName))
????????????{
????????????????//調用目標對象Save方法
????????????????target.Save();
????????????}
????????????else
????????????{
????????????????Console.WriteLine("您沒有該權限");
????????????}
????????}
????}
?
這樣,CompanyManager類就不必與判斷權限的類SecurityManager耦合,但是這種方式實現起來比較麻煩。
?
第三種實現方式,Spring.NET提供的AOP:AopAlliance.Intercept.IMethodInterceptor接口和ProxyFactory類的組合。
????public?class?AroundAdvice?:?IMethodInterceptor
????{
????????//權限系統類(可外部注入)
????????private?ISecurityManager?manager?=?new?Service.SecurityManager();
????????public?object?Invoke(IMethodInvocation?invocation)
????????{
????????????//攔截Save方法
????????????if?(invocation.Method.Name?==?"Save")
????????????{
????????????????ICompanyManager?target?=?(ICompanyManager)invocation.Target;
????????????????return?manager.IsPass(target.UserName)???invocation.Proceed()?:?null;
????????????}
????????????else
????????????{
????????????????return?invocation.Proceed();
????????????}
????????}
????}
?
Program????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????ICompanyManager?target?=?new?CompanyManager()?{?Dao?=?new?CompanyDao(),?UserName?=?"admin"?};
????????????
????????????ProxyFactory?factory?=?new?ProxyFactory(target);
????????????factory.AddAdvice(new?AroundAdvice());
????????????ICompanyManager?manager?=?(ICompanyManager)factory.GetProxy();
????????????manager.Save();
????????????Console.ReadLine();
????????}
????}
?
輸出:保存數據
?
Spring.NET利用System.Reflection.Emit命名空間下的類在運行時動態創建IL代碼來生成AOP代理。這使得代理(的創建)非常高效,并且不受任何繼承層次的限制。
?
參考:Spring.NET中文手冊
李會軍博客代理模式http://www.cnblogs.com/terrylee/archive/2006/05/18/403382.html
?
代碼下載
?
?
返回目錄
總結
以上是生活随笔為你收集整理的Spring.NET学习笔记12——面向切面编程(基础篇) Level 300的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到女儿生病是什么意思周公解梦
- 下一篇: asp.net动态加载css