AOP架構是Spring.NET的一個關鍵元件。Spring.NET的IoC容器與AOP架構是互相獨立的,兩者完全可以不依賴對方而單獨使用,但是AOP做為一個強大的中間件解決方案,完善了IoC容器的功能。
先看一個概念:
通知(Advice):AOP架構在某個連接配接點所采取的行為。通知有多種類型,包括“環繞”通知,“前置”通知和“異常”通知等,後文将對通知類型進行讨論。包括Spring.NET在内的很多AOP架構都把通知模組化為攔截器(interceptor),并且會維護一個"包圍"在連接配接點周圍的攔截器鍊。
然後我們看一個“前置”通知的例子:
1.先做一個目标對象(Target object),既要被通知的對象。目前Spring.NET的AOP架構要求目标對象必須實作一個以上接口。也就是說,要想讓AOP架構支援某個類,該類必須實作至少一個接口。實際上這個限制并沒有乍聽起來那麼麻煩:在任何情況下,面向接口程式設計都是一個好的習慣。(未來版本的Spring.NET AOP架構已經計劃支援代理沒有實作任何接口的類。)
接口代碼如下:
namespace HelloWorld
{
public interface ITestClass
{
void aopTest();
}
}
實作類代碼:
using System;
namespace HelloWorld
{
public class TestClass:ITestClass
{
public TestClass()
{
System . Console.WriteLine("TestClass 被建立");
}
public void aopTest()
{
Console.WriteLine("TestClass 方法執行 ");
}
}
}
2.前置通知,要實作IMethodBeforeAdvice
代碼如下:
using System;
namespace HelloWorld
{
public class BeforeAdvice:Spring .Aop.IMethodBeforeAdvice
{
public void Before(System.Reflection.MethodInfo method, object[] args, object target)
{
Console.WriteLine("前置通知");
}
}
}
3.主程式
using System;
using Spring.Aop.Framework;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
ProxyFactory factory = new ProxyFactory(new TestClass() );
factory.AddAdvice(new BeforeAdvice());
ITestClass helloProxy = (ITestClass)factory.GetProxy();
helloProxy.aopTest();
Console.ReadLine();
}
}
}
運作程式:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIH5EUuEDM0UHdvwFNxkDM5ADMy8CXzV2Zh1WS5JHduV0LcVTMuFWaqdmbhl3LcRXZu9lbkN3Yfd2bsJ2Xw9CXzV2Zh1WavwFdl5mLuR2cj5yZvxmYtA3Lc9CX6MHc0RHaiojIsJye.png)
我們可以看到在方法aoptest()被執行前,前置通知被執行。同理我們可以加入“環繞”通知,“異常”通知和後置通知。
“環繞”通知要繼承IMethodInterceptor接口,,“異常”通知要繼承IThrowsAdvice接口,後置通知要繼承AfterAdvice 。
我們還可以完全用配置檔案來實作,達到無浸入的目的。
修改app.config 如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net" >
<object id="TC" type="HelloWorld.TestClass" />
<object id="BAdvice" type="HelloWorld.BeforeAdvice" />
<object id="testclass" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop" >
<property name="ProxyInterfaces">
<list>
<value>HelloWorld.ITestClass</value>
</list>
</property>
<property name="Target">
<ref object="TC" />
</property>
<property name="InterceptorNames">
<list>
<value>BAdvice</value>
</list>
</property>
</object>
</objects>
</spring>
</configuration>
當然主程式也要改下:
using System;
using Spring.Aop.Framework;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
IApplicationContext objectfactory = ContextRegistry.GetContext();
ITestClass helloProxy = (ITestClass)(objectfactory.GetObject("testclass"));
helloProxy.aopTest();
Console.ReadLine();
}
}
}
搞定 ,我們實作了一個簡單的通知。