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


       

    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动态切入点,需要自定义

    先到此为止

  • 相关阅读:
    getResources().getXml()获取xml
    android中处理XML的方式
    财务管理
    关于Android界面编程与视图(View)组件
    韩正:上海千万不能出方向性失误
    scaletype
    有钱花
    static readonly const
    关于android:focusable属性
    Android中focusable属性的妙用——底层按钮的实现
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1554115.html
Copyright © 2020-2023  润新知