上篇我学习了Spring.NET的四种通知类型,AOP的实现方案比较复杂,是通过代码实现的。而Spring.NET框架给我们提供了配置的方式来实现AOP的功能。到目前为止,我们已经讨论过使用ProxyFactoryObject或其它类似的工厂对象显式创建AOP代理的方法。如果应用程序需要创建很多AOP代理,比如当需要代理某个服务层的所有对象时,这种方法就会使配置文件变的相当庞大。为简化配置过程,Spring.NET提供了“自动代理”的功能,可以根据条件自动创建代理对象,也就是说,可以将多个对象分组以作为要代理的候选对象。自动代理使用起来比较简单和方便。我仔细分析了一下,提供的几种配置差异主要在于切入点的方式不同。目前我实现了三种切入点的配置方式。

  首先我们先来看一下准备环境。  

通知
    public class AroundAdvice : IMethodInterceptor
    {
        public object Invoke(IMethodInvocation invocation)
        {
            Console.WriteLine("开始:  " + invocation.TargetType.Name + "." + invocation.Method.Name);
            object result = invocation.Proceed();
            Console.WriteLine("结束:  " + invocation.TargetType.Name + "." + invocation.Method.Name);
            return result;
        }
    }

  

目标对象
    public interface IService
    {
        IList FindAll();

        void Save(object entity);
    }

    public class CategoryService : IService
    {
        public IList FindAll()
        {
            return new ArrayList();
        }

        public void Save(object entity)
        {
            Console.WriteLine("保存:" + entity);
        }
    }

    public class ProductService : IService
    {
        public IList FindAll()
        {
            return new ArrayList();
        }

        public void Save(object entity)
        {
            Console.WriteLine("保存:" + entity);
        }
    }

  一、对象名称切入点:ObjectNameAutoProxyCreator  

  ObjectNameAutoProxyCreator可以用特定的文本值或通配符匹配目标对象的名称,并为满足条件的目标对象创建AOP代理。该类支持模式匹配字符串,如:"*name","name*",”*name*“和精确文本如"name"。我们可以通过下面这个简单的例子了解一下自动代理的功能。

App.config
      <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
        <property name="ObjectNames">
          <list>
            <value>*Service</value>
          </list>
        </property>
        <property name="InterceptorNames">
          <list>
            <value>aroundAdvice</value>
          </list>
        </property>
      </object>

<object id="aroundAdvice" type="Common.AroundAdvice, Common"/>
      
      <object id="categoryService" type="Service.ProductService, Service"/>
      <object id="productService" type="Service.ProductService, Service"/>

Program
class Program
    {
        static void Main(string[] args)
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            IDictionary speakerDictionary = ctx.GetObjectsOfType(typeof(IService));
            foreach (DictionaryEntry entry in speakerDictionary)
            {
                string name = (string)entry.Key;
                IService service = (IService)entry.Value;
                Console.WriteLine(name + " 拦截: ");

                service.FindAll();

                Console.WriteLine();

                service.Save("数据");

                Console.WriteLine();
            }


            Console.ReadLine();
        }
    }

  输出效果:图1
图1

  使用ObjectNameAutoProxyCreator经常需要对要拦截的方法进行筛选,这时我用到Spring.Aop.Support.NameMatchMethodPointcutAdvisor,稍微修改一下配置:

App.config
      <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
        <property name="ObjectNames">
          <list>
            <value>*Service</value>
          </list>
        </property>
        <property name="InterceptorNames">
          <list>
            <value>aroundAdvisor</value>
          </list>
        </property>
      </object>

<object id="aroundAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop">
        <property name="Advice" ref="aroundAdvice"/>
        <property name="MappedNames">
          <list>
            <value>Find*</value>
          </list>
        </property>
      </object>

<object id="aroundAdvice" type="Common.AroundAdvice, Common"/>

  输出效果:图2
图2

  MappedNames的配置为:Find*,因此能够拦截到FindAll方法。

  二、正则表达式切入点:RegularExpressionMethodPointcutAdvisor和SdkRegularExpressionMethodPointcut
  DefaultAdvisorAutoProxyCreator类会在当前容器中自动应用满足条件的Advisor,而不用在自动代理Advisor的对象定义中包含特定的对象名。它既可以保持配置文件的一致性,又可避免ObjectNameAutoProxyCreator引起的配置文件的臃肿。

  先来说RegularExpressionMethodPointcutAdvisor。

App.config
      <object id="aroundAdvisor" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
        <property name="advice" ref="aroundAdvice"/>
        <property name="patterns">
          <list>
            <value>.*Find*.*</value>
          </list>
        </property>
      </object>

<!--必须让Spring.NET容器管理DefaultAdvisorAutoProxyCreator类-->
      <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>

<object id="aroundAdvice" type="Common.AroundAdvice, Common"/>

<object id="categoryService" type="Service.ProductService, Service"/>
      <object id="productService" type="Service.ProductService, Service"/>

输出效果:图3
图3

  以上配置相对复杂一点。使用SdkRegularExpressionMethodPointcut的配置就相对简单的多,而项目中SdkRegularExpressionMethodPointcut也经常用到。
  SdkRegularExpressionMethodPointcut只需要简单的配置一下通知和切入点就完成了。

App.config
      <object id="advisor" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
        <property name="pattern" value="Service.*"/>
      </object>

<aop:config>
        <aop:advisor pointcut-ref="advisor" advice-ref="aroundAdvice"/>
      </aop:config>

<object id="aroundAdvice" type="Common.AroundAdvice, Common"/>

<object id="categoryService" type="Service.ProductService, Service"/>
      <object id="productService" type="Service.ProductService, Service"/>

输出效果:图4

图4

  pattern属性为拦截表达式。Service.*的意思是,拦截Service命名空间下(包括子空间)的所有类。如果改为Service.*.Find*",意思为拦截Service命名空间下(包括子空间)的所有类以Find开头的方法或Service命名空间下以Find开头的所有类
输出效果:图5

图5

  三、属性切入点:AttributeMatchMethodPointcutAdvisor
Spring.NET框架运行开发人员自定义属性,拦截标注带有特定属性的类中的方法。

Attribute
    public class ConsoleDebugAttribute : Attribute
    {

}

public class AttributeService : IService
    {
        [ConsoleDebug]
        public IList FindAll()
        {
            return new ArrayList();
        }

public void Save(object entity)
        {
            Console.WriteLine("保存:" + entity);
        }
    }

App.config
      <object id="aroundAdvisor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
        <property name="Advice" ref="aroundAdvice"/>
        <property name="Attribute"
                  value="ConfigAttribute.Attributes.ConsoleDebugAttribute, ConfigAttribute" />
      </object>
      
      <object id="proxyFactoryObject" type="Spring.Aop.Framework.ProxyFactoryObject">
        <property name="Target">
          <object type="ConfigAttribute.Service.AttributeService, ConfigAttribute" />
        </property>
        <property name="InterceptorNames">
          <list>
            <value>aroundAdvisor</value>
          </list>
        </property>
      </object>

<object id="aroundAdvice" type="Common.AroundAdvice, Common"/>

  输出效果:图6
图6

  代码下载

  返回目录

转载于:https://www.cnblogs.com/GoodHelper/archive/2009/11/16/SpringNet_Aop_Config.html

Spring.NET学习笔记15——AOP的配置(基础篇) Level 200相关推荐

  1. Spring.NET学习笔记13——AOP的概念(基础篇) Level 200

    上篇我们简单的了解了AOP的应用场景,知道AOP编程的重要性.这篇我们先看一段代码,来开始今天的学习. 回顾与上篇类似的代码:SecurityService类的IsPass判断用户名为"ad ...

  2. Spring.NET学习笔记10——方法的注入(基础篇) Level 200

    多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...

  3. Spring.NET学习笔记11——自定义对象行为(基础篇) Level 200

    Spring.NET通过几个专门的接口来控制容器中对象的行为.说到对象的行为无非就要提到对象的生命周期控制.类似在WinForm开发,Form生命周期中,Load方法为Form的载入方法和Dispos ...

  4. Spring.NET学习笔记12——面向切面编程(基础篇) Level 300

    AOP即面向切面编程(Aspect Oriented Programming的缩写),是OOP(面向对象编程)的一种延续形式.是通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添 ...

  5. 点云学习笔记15——PCL常用的基础代码

    点云学习笔记15--PCL基础 命名规范 常用代码 1.时间计算 2.pcl::PointCloud::Ptr和pcl::PointCloud的两个类相互转换 3.如何查找点云的x,y,z的极值? 4 ...

  6. 动力节点王鹤SpringBoot3学习笔记——第二章 掌握SpringBoot基础篇

    目录 二.掌控SpringBoot基础篇 2.1 Spring Boot ? 2.1.1 与Spring关系 2.1.2 与SpringCloud关系 2.1.3  最新的Spring Boot3 新 ...

  7. Spring.NET学习笔记1——控制反转(基础篇) Level 200

    在学习Spring.NET这个控制反转(IoC)和面向切面(AOP)的容器框架之前,我们先来看一下什么是控制反转(IoC). 控制反转(Inversion of Control,英文缩写为IoC),也 ...

  8. Spring.NET学习笔记8——集合类型的注入(基础篇) Level 200

    Spring.NET还支持集合类型的注入.而且使用起来也比较方便. 一.ILIst类型 使用<list>元素作为ILIst的标签,value为集合中元素的值.也可以注入对象,甚至关联其它对 ...

  9. 黑马程序员C++学习笔记<第一阶段_基础篇>

    配套视频网址: 黑马程序员:http://yun.itheima.com/course/520.html?bili B站:https://www.bilibili.com/video/BV1et411 ...

最新文章

  1. Checked ==true ? Y:N ;
  2. Console-算法[]-数组求最大值和最小值(只能遍历一次)
  3. 数字图像基础,分辨率
  4. Can not create a Path from an empty string解决
  5. 中国城市人口分布区域分析
  6. python是属于it界吗_转行IT行业,Python是不是一个好的选择?
  7. 分享一个引起极度舒适的工作桌面
  8. 【个人重点】开发中应该重视的几点
  9. linux网络发包性能优化
  10. 移动端报表JS开发示例--获取定位
  11. Nginx学习笔记:基础
  12. codeforces:ProblemMset
  13. cacti mysql版本,cacti迁移+升级版本
  14. IDEA 方法自动添加注释
  15. APICloud的config.xml应用配置的说明
  16. 追梦App系列博客——后端架构篇
  17. 详解条件概率,全概率,贝叶斯公式
  18. 武汉计算机软件应届毕业生工资,精打细算告诉你一个应届毕业生在武汉工资多少才能活下来(汉口物件)...
  19. java服务器如何群发消息,java TCP编程简单实现一个消息群发功能
  20. 我国网民规模近10亿:4成初中学历 近3成月收入超5000元

热门文章

  1. Android中DisplayMetrics 获取手机屏幕分辨率
  2. [Ting's笔记Day6]活用套件carrierwave gem:(1)在Rails实现图片上传功能
  3. 关于fragment中使用onActivityResult
  4. 《Thinking in java》 读了个开头
  5. [Vue.js] 基础 -- 安装Vue
  6. typedef四用途与两陷阱
  7. HTTP CORS(HTTP-同源策略)
  8. 卢克增加服务器,DNF卢克攻坚服务器优化:增加攻坚队频道,新跨区整合计划
  9. 没串口怎么操作核心板的Linux?ADB(以点灯为例)
  10. python sum 数组原理_Python – Sum 4D数组