Spring.Net 面向切面AOP

Spring.Net和Log4net、NUnit、NHibernate一样,也是先从Java中流行开来,然后移植到了.NET当中,形成了.NET版的Spring框架。其官方网站为:http://www.springframework.net/index.html

首先看一下Spring.Net的架构图:


根据架构图可以看到,它的底层核心是Spring Core,上层是AOP层。其它的什么NHibernate、ES、WCF都基于这两个底层。

看了这个架构图只是了解了Spring框架所提供的功能,那么Spring.Net究竟是什么呢?它对我们开发来说究竟有什么样的帮助呢?

简单来说,Spring.Net是一个关注.NET企业应用开发的应用程序框架。它的核心思想是AOP(面向切面编程或者叫面向方面编程),与面向对象不同,它关注的是程序的“切面”,即横向的内容(比如日志、验证等通用型的功能)。随着软件系统规模的不断升级,复杂程度越来越高,面向对象就有了它的弊端,这时候引入AOP就能有效的解决问题。从系统中分离出来方面,然后集中实现。从而可以独立编写业务逻辑代码和方面代码,在系统运行的时候,再将方面代码“织入”到系统中,使得系统的功能得以扩展。

提到Spring.Net除了想到AOP之外,还有一个就是IOC(控制反转)或者DI(依赖注入)。主要意思就是明确的定义组件接口,独立的开发各个组件,然后通过组件之间的依赖关系进行组装,进而成为一个完整的系统。

好了,我从来不喜欢讲太多的理论,我喜欢用一些小例子让大家快速的上手这个技术。由于Spring.Net是个相对比较庞大的内容,因此下面就介绍一下具体使用Spring.Net实现AOP的过程。

首先先下载Spring.Net。这个可以在官方链接中找到或者百度下一个。目前最新的版本号为1.3.2,建议读者下载最新版本。

如果你下的是zip包,可以直接解压缩。如果是msi安装包,则你可以选择路径进行安装。里面有Spring.Net的核心dll文件、doc文档和一些例子。由于Spring.Net是开源的,因此你还会看到有项目的源代码在里面,对底层源码感兴趣的读者也可以拿出来学习使用。

一、建立一个类库项目BIZ

BIZ是一个业务逻辑处理模块,首先定义一个业务接口以及其实现类:

  1. namespace BIZ.Commands  
  2. {  
  3.     public interface IStudentService  
  4.     {  
  5.         void GoToSchool(string studentName, string className);  
  6.     }  
  7. }  
namespace BIZ.Commands
{
    public interface IStudentService
    {
        void GoToSchool(string studentName, string className);
    }
}

  1. namespace BIZ.Commands  
  2. {  
  3.     public class StudentService : IStudentService  
  4.     {  
  5.         public void GoToSchool(string studentName, string className)  
  6.         {  
  7.             Console.WriteLine("计算机({1})班的{0}同学去上学了。。。", studentName, className);  
  8.         }  
  9.     }  
  10. }  
namespace BIZ.Commands
{
    public class StudentService : IStudentService
    {
        public void GoToSchool(string studentName, string className)
        {
            Console.WriteLine("计算机({1})班的{0}同学去上学了。。。", studentName, className);
        }
    }
}
这里我模拟一下任务,就是一个学生去上学的业务逻辑处理。

接下来,在这个项目中建立一个LogBeforeAdvice类并实现IMethodBeforeAdvice接口。这里面需要添加引用Spring.Net的一些dll文件,比如Spring.Core、Spring.Aop等,这些都可以在Spring.Net目录中找到。

  1. namespace BIZ.Aspects  
  2. {  
  3.     public class LogBeforeAdvice : IMethodBeforeAdvice  
  4.     {  
  5.         public void Before(System.Reflection.MethodInfo method, object[] args, object target)  
  6.         {  
  7.             Console.WriteLine("拦截的方法名—>" + method.Name);  
  8.             Console.WriteLine("目标—>" + target);  
  9.             Console.WriteLine("参数—>");  
  10.             if (args != null)  
  11.             {  
  12.                 foreach (object arg in args)  
  13.                 {  
  14.                     Console.WriteLine("\t: " + arg);  
  15.                 }  
  16.             }  
  17.         }  
  18.     }  
  19. }  
namespace BIZ.Aspects
{
    public class LogBeforeAdvice : IMethodBeforeAdvice
    {
        public void Before(System.Reflection.MethodInfo method, object[] args, object target)
        {
            Console.WriteLine("拦截的方法名—>" + method.Name);
            Console.WriteLine("目标—>" + target);
            Console.WriteLine("参数—>");
            if (args != null)
            {
                foreach (object arg in args)
                {
                    Console.WriteLine("\t: " + arg);
                }
            }
        }
    }
}
这里需要说明一下,这里实现的接口叫“前置通知”,除此之外还有“后置通知”、“环绕通知”、“异常通知”等共四种类型的通知。

前置通知是在方法执行前自动执行的通知;后置通知是在方法执行后自动执行的通知;环绕通知可以在方法调用前执行通知代码,可以决定是否还调用目标方法;异常通知是方法抛出异常时自动执行的方面代码。(注:其它三种通知可以自行添加实现,这里只演示前置通知。)

二、建立一个控制台应用程序SpringNetAop

在App.config(新版本的VS都能够自动生成这个文件,如果没有自动新建一个)中,添加Spring.Net的相关配置:

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.   <configSections>  
  4.     <sectionGroup name="spring">  
  5.       <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />  
  6.       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />  
  7.     </sectionGroup>  
  8.   </configSections>  
  9.   
  10.   <spring>  
  11.     <context>  
  12.       <resource uri="config://spring/objects"/>  
  13.     </context>  
  14.   
  15.     <objects xmlns="http://www.springframework.net">  
  16.       <description>AOP例子</description>  
  17.       <object id="beforeAdvice" type="BIZ.Aspects.LogBeforeAdvice,BIZ"/>  
  18.       <object id="myStudentService" type="Spring.Aop.Framework.ProxyFactoryObject">  
  19.         <property name="Target">  
  20.           <object type="BIZ.Commands.StudentService, BIZ" />  
  21.         </property>  
  22.         <property name="InterceptorNames">  
  23.           <list>  
  24.             <value>beforeAdvice</value>  
  25.           </list>  
  26.         </property>  
  27.       </object>  
  28.     </objects>  
  29.   
  30.   </spring>  
  31. </configuration>  
<?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">
      <description>AOP例子</description>
      <object id="beforeAdvice" type="BIZ.Aspects.LogBeforeAdvice,BIZ"/>
      <object id="myStudentService" type="Spring.Aop.Framework.ProxyFactoryObject">
        <property name="Target">
          <object type="BIZ.Commands.StudentService, BIZ" />
        </property>
        <property name="InterceptorNames">
          <list>
            <value>beforeAdvice</value>
          </list>
        </property>
      </object>
    </objects>

  </spring>
</configuration>

这里面就是核心的配置内容。通过config文件装配需要注入的对象并织入到StudentService这个业务逻辑类中,这样就完成了组装。

然后在Program.cs中写入如下代码:

  1. namespace SpringNetAop  
  2. {  
  3.     class Program  
  4.     {  
  5.         static void Main(string[] args)  
  6.         {  
  7.             IApplicationContext context = ContextRegistry.GetContext();  
  8.             IStudentService command = (IStudentService)context["myStudentService"];  
  9.             command.GoToSchool("guwei4037""一");  
  10.         }  
  11.     }  
  12. }  
namespace SpringNetAop
{
    class Program
    {
        static void Main(string[] args)
        {
            IApplicationContext context = ContextRegistry.GetContext();
            IStudentService command = (IStudentService)context["myStudentService"];
            command.GoToSchool("guwei4037", "一");
        }
    }
}
同样的也需要引用Spring.Core和Spring.Aop的dll文件。

好,运行一下控制台程序。

可以看到,在我调用上学的方法时,先执行了方面代码里的内容。

通过这个例子,我们认识到Spring.Net可以根据需要动态的装配组件,并可以在执行某个方面代码前自动执行我们所要的操作。可以想象,这个功能完全可以使用在我们对业务操作进行日志记录的场合,在调用方法时还是去上学,但是通过前置通知我们增加了日志记录功能。

好了,关于Spring.Net的AOP部分就讲解到这里,这里只是简单讲解了一小部分的Spring.Net的内容,主要目的是让大家对Spring.Net有个基本的认识。如果需要更多详细的资料,可以查看相关文档资料:http://www.springframework.net/documentation.html
原文地址:http://blog.csdn.net/chinacsharper/article/details/19295103

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值