好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

spring.net结合普通三层(实现IOC 及AOP中的异常记录功能)

spring.net结合普通三层(实现IOC 及AOP中的异常记录功能)

spring.net结合普通三层(实现IOC 及AOP中的异常记录功能)

 

 

首先先引用一下AOP相关知识;

AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。
 
OOP是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系;AOP是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。
 
AOP是使用切面(aspect)将横切关注点模块化,OOP是使用类将状态和行为模块化。在OOP的世界中,程序都是通过类和接口组织的,使用它们实现程序的核心业务逻辑是十分合适。但是对于实现横切关注点(跨越应用程序多个模块的功能需求)则十分吃力,比如日志记录,验证等

最近一直在学习spring.net的知识;结合先前学习的内容做一个跟普通三层相结合的实例;主要是演示spring.net中关于AOP的功能;首先了解一下我实例的项目架构;

其中ISpringNetBLL,ISpringNetDAL分别为逻辑层跟数据层的接口层;因为本实例重点是运用结合spring.net所以代码都是非常简单;并无结合数据库的操作;

具体代码分别如下:

?

using   System;

using   System.Collections.Generic;

using   System.Linq;

using   System.Text;

 

namespace   ISpringNetBLL

{

     //可以给BLL层定义一个统一的接口 然后再定义一个抽象类来继承接口

 

     public   interface   IUserOperate

     {

         string   UserLogin( string   UserName);

     }

}

  

?

using   System;

using   System.Collections.Generic;

using   System.Linq;

using   System.Text;

using   Spring.Core;

using   Spring.Context;

using   Spring.Context.Support;

namespace   ISpringNetBLL

{

     public   abstract   class   BaseBLL:IUserOperate

     {

         public   BaseBLL()

         {

              

         }

 

         public   abstract   string   UserLogin( string   UserName);

     }

}

  

?

using   System;

using   System.Collections.Generic;

using   System.Linq;

using   System.Text;

 

namespace   ISpringNetDAL

{

     public   interface   IUserOperateDAL

     {

         string   UserLogin( string   UserName);

     }

}

接下来我们看一下SpringNetAop层的内容;此层主要是实现一些AOP的代码,以及特性和一个统一调用spring.net的类;记录日志我们使用Log4Net来实现;

1:Aspects 文件夹里存放的几个类分别是Spring.net几种AOP的通知模式;因为本实例主要是要演示异常的调用所以我们调用的是类LoggingThrowsAdvice.cs;有关Log4Net的运用大家可以搜索一下,不是本文的重点;这边有个要注意此处是类库运用Log4net,所以在读取配置文件时要写成@"bin\\Log4Net.config";而配置文件Log4Net.config属性要设置为:始终复制  嵌入的资源;

?

using   System.Linq;

using   System.Text;

using   SpringNetCommon;

using   System.Reflection;

using   Spring.Aop;

using   log4net;

using   log4net.Core;

 

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"bin\\Log4Net.config" , Watch = true )]

namespace   SpringNetAop.Aspects

{

     public   class   LoggingThrowsAdvice:IThrowsAdvice

     {

         private   ILog logger;

         public   LoggingThrowsAdvice()

         {

             logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

             log4net.Config.XmlConfigurator.Configure( new   System.IO.FileInfo( "Log4Net.config" ));

         }

 

         public   void   AfterThrowing(Exception ex)

         {

             logger.Warn(

                 String.Format( "异常的内容为: {0}" , ex));

         }

     }

}

Log4Net.config配置的内容如下:配置实现的功能是每天生成一个记录文件

 <?  xml version="1.0" encoding="utf-8"   ?> 
 <  configuration  > 
   <  configSections  > 
     <  section   name  ="log4net"   type  ="System.Configuration.IgnoreSectionHandler"   /> 
   </  configSections  > 
   <  log4net  > 
     <  appender   name  ="RollingLogRootFileAppender"   type  ="log4net.Appender.RollingFileAppender"  > 
       <!--  日志的路径  --> 
       <  file   value  =".\Log\WanLog"   /> 
       <!--  是否覆盖,默认是追加true  --> 
       <  appendToFile   value  ="true"  /> 
       <!--  文件滚动周期(每日创建新日志文件)  --> 
       <  datePattern   value  ="yyyyMMdd&quot;.txt&quot;"  /> 
       <!--  设置无限备份=-1 ,最大备份数为1000  --> 
       <  maxSizeRollBackups   value  ="1000"  /> 
       <!--  名称是否可以更改为false为可以更改  --> 
       <  staticLogFileName   value  ="false"   /> 
       <!--  文件滚动选项Composite表示根据日期和大小来滚动  --> 
       <  rollingStyle   value  ="Composite"   /> 
       <  layout   type  ="log4net.Layout.PatternLayout"  > 
         <  param   name  ="ConversionPattern"   value  ="%d{yyyy-MM-dd HH:mm:ss}[%t][%-5p][%c]%m%n%exception%n"   /> 
       </  layout  > 
     </  appender  > 
     <  root  > 
       <  level   value  ="All"   /> 
       <  appender-ref   ref  ="RollingLogRootFileAppender"   /> 
     </  root  > 
   </  log4net  > 
 </  configuration  > 


2:Attributes存放的是一个重写的特性;spring.net特性来定位要调用AOP;这边主要注意是要继承Attribute;

 using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;

  namespace   SpringNetAop.Attributes
{
      public   class   LoggingAttributes:Attribute
    {
          public   LoggingAttributes()
        {
 
        }
    }
} 

3:SpringNetHelp文件夹存放的是一个统一调用spring.net的类;因为我把spring.net的配置文件存放在UI层;所以要注意调用的路径问题;配置文件我们在UI层进行;

 using   Spring.Core;
  using   Spring.Context;
  using   Spring.Context.Support;
  using   Spring.Core.IO;
  using   Spring.Objects.Factory;
  using   Spring.Objects.Factory.Xml;
  namespace   SpringNetAop.SpringNetHelp
{
      public   class   GetAppContext
    {
          private   static  IApplicationContext applicationContext =  null  ;

          public   GetAppContext()
        {
 
        }

          public   static   IApplicationContext ApplicationContext
        {
              get  
            {
                applicationContext  =  new  XmlApplicationContext( "  ~/Config/Objects.xml  "  );
                  return   applicationContext;
            }
        }
    }
} 


接下来我们看一下逻辑层跟数据层的代码;

首先看一下数据层的代码;我们为要进行异常记录的方法加上特性[LoggingAttributes]

 using   System.Linq;
  using   System.Text;
  using   ISpringNetDAL;
  using   SpringNetAop.Attributes;
  namespace   SpringNetDAL
{
      public   class   UserOperateDAL:IUserOperateDAL
    {
        [LoggingAttributes]
          public   string  UserLogin( string   UserName)
        {
               throw   new  Exception( "  我是DAL层的异常  "  );
        }
    }
} 

看BLL层的具体代码如下:

 using   Spring.Core;
  using   SpringNetAop;
  using   Spring.Core.IO;
  using   Spring.Objects.Factory.Xml;
  using   Spring.Objects.Factory;
  using   Spring.Context.Support;
  using   Spring.Context;
  namespace   SpringNetBLL
{
      public   class   UserOperate:BaseBLL
    {
          private  IUserOperateDAL _userOperatedal =  null  ;

          public   UserOperate()
        {
        }

        [LoggingAttributes]
          public   override   string  UserLogin( string   UserName)
        {
              //   throw new Exception("我是BLL层异常内容啊"); 
             _userOperatedal = (IUserOperateDAL)SpringNetAop.SpringNetHelp.GetAppContext.ApplicationContext.GetObject( "  UserOperateDal  "  );
               return   _userOperatedal.UserLogin(UserName);   
        }
    }
} 


接着看一下UI层;这边主要是两个配置文件就是Objects.xml 以及App.config; 其中Objects.xml文件的属性设置:始终复制  生成操作为内容;

App.config的内容如下(关于spring.net配置的说明大家可以搜索园内的spring.net知识或者可以查看spring.net提供的帮助手册,都有很详细的说明):

 <?  xml version="1.0"  ?> 
 <  configuration  > 

   <  configSections  > 
     <  sectionGroup   name  ="spring"  > 
       <!--  提供Spring对应用程序上下文的支持  --> 
       <  section   name  ="context"   type  ="Spring.Context.Support.ContextHandler, Spring.Core"  /> 
       <!--  提供Spring对 对象容器的支持  --> 
       <  section   name  ="objects"   type  ="Spring.Context.Support.DefaultSectionHandler, Spring.Core"  /> 
     </  sectionGroup  > 
   </  configSections  > 

   <  spring  > 
     <  context  > 
       <  resource   uri  ="file://~/Config/Objects.xml"  /> 
       <!--  <resource uri="assembly://SpringNetUI/SpringNetUI.Config/Objects.xml"/>  --> 
     </  context  > 
   </  spring  > 
  
 </  configuration  > 

Objects.xml文件的内容:

 <?  xml version="1.0" encoding="utf-8"   ?> 
 <  objects   xmlns  ="http://www.springframework.net"   xmlns:xsi  ="http://www.w3.org/2001/XMLSchema-instance"  > 

   <  object   name  ="UserOperateDal"   type  ="SpringNetDAL.UserOperateDAL,SpringNetDAL"  /> 
  
   <!--  环绕通知拦截  运用特性  --> 
   <  object   id  ="aroundAdvisor"   type  ="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop"  > 
     <  property   name  ="Advice"  > 
       <  object   type  ="SpringNetAop.Aspects.LoggingAroundAdvice, SpringNetAop"   /> 
     </  property  > 
     <  property   name  ="Attribute"  
              value  ="SpringNetAop.Attributes.LoggingAttributes, SpringNetAop"   /> 
   </  object  > 

  
   <!--  后置通知拦截  运用名称  --> 
   <  object   id  ="afterAdvisor"   type  ="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"  > 
     <  property   name  ="Advice"  > 
       <  object   type  ="SpringNetAop.Aspects.LoggingAfterAdvice, SpringNetAop"   /> 
     </  property  > 
     <  property   name  ="MappedNames"  > 
       <  list  > 
         <  value  > *UserLogin </  value  > 
       </  list  > 
     </  property  > 
   </  object  > 

   <!--  异常通知拦截  程序所有都支持 不设置条件  --> 
   <  object   id  ="throwsAdvice"    type  ="SpringNetAop.Aspects.LoggingThrowsAdvice, SpringNetAop"   /> 
  
  

   <  object   id  ="myServiceCommand"   type  ="Spring.Aop.Framework.ProxyFactoryObject"  > 
     <  property   name  ="Target"  > 
       <  object   type  ="SpringNetBLL.UserOperate, SpringNetBLL"   /> 
     </  property  > 
     <  property   name  ="InterceptorNames"  > 
       <  list  > 
         <  value  > aroundAdvisor </  value  > 
         <  value  > afterAdvisor </  value  > 
         <  value  > throwsAdvice </  value  > 
       </  list  > 
     </  property  > 
   </  object  > 
 </  objects  > 


UI层调用BLL的代码;使用的是Spring.net的IOC

 using   Spring.Context;
  using   Spring.Context.Support;
  using   Spring.Core.IO;
  using   Spring.Objects.Factory.Xml;
  using   Spring.Objects.Factory;
  using   ISpringNetBLL;
  using   SpringNetAop;
  using   SpringNetBLL;
  namespace   SpringNetUI
{
      public   partial   class   Form1 : Form
    {
          public   Form1()
        {
            InitializeComponent();
        }
          private   void  button1_Click( object   sender, EventArgs e)
        {
              try  
            {
                IUserOperate command  = (IUserOperate)SpringNetAop.SpringNetHelp.GetAppContext.ApplicationContext.GetObject( "  myServiceCommand  "  );
                command.UserLogin(  this  .textBox1.Text.Trim());
            }
              catch  
            {

            }
        }

    }
} 


运行程度得到的结果如下:

 2013-04-06 22:28:57[1][WARN ][SpringNetAop.Aspects.LoggingThrowsAdvice]异常的内容为: System.Exception: 我是DAL层的异常
   在 SpringNetDAL.UserOperateDAL.UserLogin(String UserName) 位置 F:\测试网址\SpringNETDemo\SpringNetDAL\UserOperateDAL.cs:行号 14
   在 SpringNetBLL.UserOperate.UserLogin(String UserName) 位置 F:\测试网址\SpringNETDemo\SpringNetBLL\UserOperate.cs:行号 30
   在 _dynamic_SpringNetBLL.UserOperate.UserLogin(Object , Object[] )
   在 Spring.Reflection.Dynamic.SafeMethod.Invoke(Object target, Object[] arguments)
   在 Spring.Aop.Framework.DynamicMethodInvocation.InvokeJoinpoint()
   在 Spring.Aop.Framework.AbstractMethodInvocation.Proceed()
   在 Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor.Invoke(IMethodInvocation invocation) 

本文的源代码不懂得上传;若有人需要可以留下邮箱;本文的内容是个人学习spring.net的知识,若有错误的地方欢迎指出;

 

 

 

标签:  spring.net ,  Aop ,  异常记录

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于spring.net结合普通三层(实现IOC 及AOP中的异常记录功能)的详细内容...

  阅读:36次