Spring.NET学习笔记(6)-基础AOP

来源:互联网 发布:adobe indesign mac 编辑:程序博客网 时间:2024/05/20 13:07

1.在我们的系统中,常常要对操作进行记录,比如说某某人新增了一笔数据,然后在数据库中增加一笔操作记录

2.前端开发人员往往会在ajax调用后端的时候,调用之前先做一些数据检验的工作,调用之后对于返回的数据ui做出一些反应

3.后端开发人员有时候会做一个数据的ing和ed事件操作,比如插入数据,InsertIng和Inserted事件.

以上的种种反应在进行一个方法的操作,往往还有着其他的关联,这被我们称之为耦合,系统越大,关联越多。再比如添加日志这个功能,某天就不要了,但添加日志的代码与新增数据的代码是写在一起的,这时候就必须做出修改。

对于这些问题,我们就可以用AOP来解决。关于AOP有很多概念,我们直接看代码,不多概念。


1.通知

(1)前后通知和抛错通知,以接口来实现

public class ConsoleLoggingBeforeAdvice : IMethodBeforeAdvice{    public void Before(MethodInfo method, object[] args, object target)    {        Console.Out.WriteLine("Intercepted call to this method : " + method.Name);        Console.Out.WriteLine("    The target is       : " + target);        Console.Out.WriteLine("    The arguments are   : ");        if(args != null)        {            foreach (object arg in args)            {                Console.Out.WriteLine("/t: " + arg);            }        }    }}

public class ConsoleLoggingAfterAdvice : IAfterReturningAdvice{    public void AfterReturning(        object returnValue, MethodInfo method, object[] args, object target)    {        Console.Out.WriteLine("This method call returned successfully : " + method.Name);        Console.Out.WriteLine("    The target was      : " + target);        Console.Out.WriteLine("    The arguments were  : ");        if (args != null)        {            foreach (object arg in args)            {                Console.Out.WriteLine("/t: " + arg);            }        }        Console.Out.WriteLine("    The return value is : " + returnValue);    }}

public class ConsoleLoggingThrowsAdvice : IThrowsAdvice{    public void AfterThrowing(Exception ex)    {        Console.Error.WriteLine(            String.Format("Advised method threw this exception : {0}", ex.Message));    }}


执行每个方法时都会触发通知,注意当设置属性的时候也会触发(因为属性是伪方法)

// Create AOP proxy programmatically.ProxyFactory factory = new ProxyFactory(new ServiceCommand());factory.AddAdvice(new ConsoleLoggingBeforeAdvice());factory.AddAdvice(new ConsoleLoggingAfterAdvice());factory.AddAdvice(new ConsoleLoggingThrowsAdvice());ICommand command = (ICommand)factory.GetProxy();command.Execute();


(2)环绕通知

即以上三个通知的集合,还可以充当拦截器的作用,阻止方法触发

public class ConsoleLoggingAroundAdvice : IMethodInterceptor{    public object Invoke(IMethodInvocation invocation)    {        Console.Out.WriteLine(String.Format(            "Intercepted call : about to invoke method '{0}'", invocation.Method.Name));        object returnValue = invocation.Proceed();        Console.Out.WriteLine(String.Format(            "Intercepted call : returned '{0}'", returnValue));        return returnValue;    }}

 

ProxyFactory factory = new ProxyFactory(new ServiceCommand());              factory.AddAdvice(new ConsoleLoggingAroundAdvice());ICommand command = (ICommand)factory.GetProxy();command.Execute();if (command.IsUndoCapable){    command.UnExecute();}

 

2.以配置文件方式配置

<object id="aroundAdvice"         type="Spring.AopQuickStart.Aspects.ConsoleLoggingAroundAdvice, Spring.AopQuickStart.Common" /><object id="throwsAdvice"         type="Spring.AopQuickStart.Aspects.ConsoleLoggingThrowsAdvice, Spring.AopQuickStart.Common" /><object id="myServiceCommand" type="Spring.Aop.Framework.ProxyFactoryObject">  <property name="Target">    <object type="Spring.AopQuickStart.Commands.ServiceCommand, Spring.AopQuickStart.Common" />  </property>  <property name="InterceptorNames">    <list>      <value>aroundAdvice</value>      <value>throwsAdvice</value>    </list>  </property></object>


3.切入点

即通知在何时(指在某个方法)执行,以上通知是不管调用什么属性和方法都通知,显然我们就需要某几个方法同志就好了,所以需要一个方法匹配的过滤,如下代码NameMatchMethodPointcutAdvisor可进行方法名字过滤,

<object id="aroundAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop">        <property name="Advice">          <object type="Spring.AopQuickStart.Aspects.ConsoleLoggingAroundAdvice, Spring.AopQuickStart.Common" />        </property>        <property name="MappedNames">          <list>            <value>*Execute</value>          </list>        </property>      </object>      <object id="throwsAdvice"               type="Spring.AopQuickStart.Aspects.ConsoleLoggingThrowsAdvice, Spring.AopQuickStart.Common" />      <object id="myServiceCommand" type="Spring.Aop.Framework.ProxyFactoryObject">        <property name="Target">          <object type="Spring.AopQuickStart.Commands.ServiceCommand, Spring.AopQuickStart.Common" />        </property>        <property name="InterceptorNames">          <list>            <value>aroundAdvisor</value>            <value>throwsAdvice</value>          </list>        </property>      </object>


除了此过滤器,只要实现IPointcutAdvisor接口的都可以,spring还提供了其他的过滤类。

1.RegularExpressionMethodPointcutAdvisor  &&  SdkRegularExpressionMethodPointcut

正则表达式匹配

<object id="settersAndAbsquatulatePointcut"    type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">  <property name="patterns">    <list>      <value>.*set.*</value>      <value>.*absquatulate</value>    </list>  </property></object>

<object id="settersAndAbsquatulateAdvisor"    type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">  <property name="advice">    <ref local="objectNameOfAopAllianceInterceptor"/>  </property>  <property name="patterns">    <list>      <value>.*set.*</value>      <value>.*absquatulate</value>    </list>  </property></object>

2.AttributeMatchMethodPointcutAdvisor

在方法上挂标签匹配

<object id="aroundAdvisor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">  <property name="Advice">    <object type="Spring.AopQuickStart.Aspects.ConsoleLoggingAdvice, Spring.AopQuickStart.Step4" />  </property>  <property name="Attribute"             value="Spring.AopQuickStart.Attributes.ConsoleLoggingAttribute, Spring.AopQuickStart.Step4" /></object>


3.DynamicMethodMatcherPointcutAdvisor动态切入点,需要自定义

先到此为止

原创粉丝点击