MVC中的AOP思想——Filter

一,AOP(Aspect Oriented Programming)

在谈AOP之前,我们先来说OOP(Object Oriented Programming),这是接触每一门编程语言的时候,都会先学的东西。众所周知,OOP有三个特征:封装,继承,多态。这是从类的角度来说的,如果我们把系统中的关系用UML图来表示的话,会发现有点儿类似树的结构,这棵树是从上到下的或者是从下到上的,是一个竖直的结构。

但是AOP不同,AOP是一个水平的结构。在一个系统中,我们可能会遇到这样的情况,当我们写了一大段业务逻辑,之后,在方法结尾,我们要将一些操作记入日志中,然而,我们要记入日志的东西很多,很可能我们很多代码都是这个结构:业务逻辑+日志记录。为解耦业务逻辑跟这些与业务逻辑无关的东西,方便系统维护,提高代码清晰度,我们加入AOP。

如果说OOP是对系统的纵切的话,那么AOP就是对系统的横切,在横切的同时,加入统一的处理,让我们编码的时候,重点还是放在业务逻辑方面,对系统整体的相似的东西(与业务逻辑无关的东西)在横切的同时统一加入。

二,Filter实现简单AOP

在ASP.NET MVC框架中,为我们提供了四种类型的Filter类型包括:IAuthorizationFilter、IActionFilter、IResultFilter、IExceptionFilter,执行顺序如下:

  • IAuthorizationFilter    最先执行的,在这些Filter中,我们可以说它的执行优先级是最高的,用于身份验证并对控制器中的action进行授等进行逻辑处理
  • IActionFilter    在IAuthorizationFilter之后执行,包含两个方法,在controller中的action执行之前、执行之后进行逻辑处理
  • IResultFilter    同样包含两个方法,在IActionFilter之后执行,在返回View之前和返回View之后执行逻辑处理
  • IException      主要用于对异常信息进行处理

下面我们以IActionFilter与IException为例,来看下filter是如何实现AOP的。

首先是actionFilter:

  public class LoggerFilter:FilterAttribute,IActionFilter
    {
        /// <summary>
        /// 在被拦截action后执行
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <remarks>创建者:刘慧超; 创建时间:2015-09-13 19:47:23</remarks>
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.Controller.ViewData["executedLogger"] = "action之后。。——" + DateTime.Now;
        }

        /// <summary>
        /// 在被拦截Action前执行
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <remarks>创建者:刘慧超; 创建时间:2015-09-13 19:47:00</remarks>
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.Controller.ViewData["executingLogger"] = "action之前。。——" + DateTime.Now;

        }
    }

我们建立的类要继承FilterAttribute,实现IActionFilter,重写action执行之前和之后的方法。

测试,如果要使用我们的filter,只需在返回view的方法上面加上标签即可。

     [LoggerFilter()]
        public ActionResult Index()
        {
            System.Threading.Thread.Sleep(2000);
            ViewData["Time"] = DateTime.Now;//当前时间
            System.Threading.Thread.Sleep(2000);

            return View();
        }

然后我们在页面上接收下根据打印的时间来判断执行顺序:

@using System.Web.UI.WebControls
@{
    ViewBag.Title = "Index";
}

<h2>测试ActionFilter</h2>

<p>@ViewData["executingLogger"]</p>

<p></p>
<p>@ViewData["Time"]</p>
<p></p>

<p>@ViewData["executedLogger"]</p>

异常处理:

 public class ExceptionFilter:FilterAttribute,IExceptionFilter
    {
        /// <summary>
        /// 异常发生时候被调用
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <remarks>创建者:刘慧超; 创建时间:2015-09-13 19:52:25</remarks>
        public void OnException(ExceptionContext filterContext)
        {
            filterContext.Controller.ViewData["ErrorMessage"] = filterContext.Exception.Message;  //此处Exception是异常类型实例
            filterContext.Result = new ViewResult()
            {
                ViewName = "ExceptionIndex",  //出错后跳转到的错误页面
                ViewData = filterContext.Controller.ViewData
            };
            filterContext.ExceptionHandled = true; //告诉系统,异常已经处理了,不需要再次处理了

        }
    }

在代码中,我们定义出现异常之后,跳转到异常出错页面。

测试方法:

  public void TestE()
        {
            throw new Exception("这是个被抛出的异常,啦啦啦。。。");
            return;
            ;
        }

        [ExceptionFilter()]
        public ActionResult ExceptionIndex()
        {
            TestE();
            return View();

        }

页面显示出一次信息:

@{
    ViewBag.Title = "ExceptionIndex";
}

<h2>异常拦截测试</h2>

<p>@ViewData["ErrorMessage"]</p>

可见filter使用方法类似,首先定义继承相应接口和特性标签的类,之后在要处理的返回视图的方法上加上attribute.

有点儿类似我们以前经常被问道的页面生命周期,但是又不一样,页面生命周期是类自带的,而filter中方法的执行是后期有选择的加入的,感觉很像方法正在从上到下流畅执行,到了特定地方,被横切一刀,切面编程还是蛮形象的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 17:25:04

MVC中的AOP思想——Filter的相关文章

ASP.NET MVC中有关AOP的编程

AOP(Aspect oriented programming)面向切面编程,主要意思是把相同.相似的并且零散的逻辑抽离出来,统一处理,这样不仅维护起来方便,也使得代码更加关注自己本身,清晰明了. 比如我们常见的权限检查,验证登陆,异常处理等都是散乱在系统各个地方,比如管理员在登陆状态才可以添加一个学生信息: public ActionResult AddStudent(Student student) { if (currentUser != null) { StudentDAL.Add(st

spring mvc中的AOP和interceptors

项目中采用Interceptor来过滤URL来决定哪些可以在不登录的情况下访问,哪些必须要登录才可以访问: public class SessionTimeoutInterceptor implements HandlerInterceptor { 此时需要在servlet.xml中配置<mvc:interceptor> 同时亦采用AOP来记录日志,使用注解方式 @Component@Aspect 同时在servlet.xml中配置 <aop:aspectj-autoproxy>&

Spring MVC 中使用AOP 进行统一日志管理--XML配置实现

1.介绍 上一篇博客写了使用AOP进行统一日志管理的注解版实现,今天写一下使用XML配置实现版本,与上篇不同的是上次我们记录的Controller层日志,这次我们记录的是Service层的日志.使用的工程还是原来的那个,具体的Spring mvc 工程搭建暂不介绍.上篇记录controller层日志的时候是将切面类组件叫给spring MVC 进行管理,因为 controller 也是交给spring MVC进行管理的,但是记录service 层日志的时候应该就应该再spring 容器中进行了,

MVC中的AOP

一 AOP是什么? AOP(Aspect-Oriented Programming),面向切面编程,看着是跟OOP(面向对象编程)挺相近的,但实际上又有什么区别呢?OOP具有封装,继承,多态等东西来定义从上到下这种层次关系,但要想实现从左到右的关系的话就开始有点水土不服了,例如用户的权限控制,操作日志等,这些与我们要实现的核心功能不大有关系的东西散布在我们代码的周边,显示十分不好看.于是我们引入了AOP的模式. 我们通常在实现一个页面逻辑的时候,通常伴随着操作日志,安全监测,事务处理等几个逻辑,

利用多态,实现一般处理程序(ashx)中的AOP(切面编程)

本文是对工作中的项目进行代码优化(完善登陆验证的AOP切面编程)时,所遇到的各种解决方案思考过程. 项目背景:由ashx+nvelocity构建的简单B/S问卷系统,现需要优化登录验证环节(时隔若干个月在回顾代码果然是一个痛苦的过程~) nvelocity是velocity框架针对.net的版本,核心是拼html字符串后返回客户端,与MVC的前后端代码隔离有异曲同工之妙.加之一般处理程序ashx不需要像asp.net那样走生成控件树的过程,执行上更是省时省力.故简单系统用ashx+nveloci

Java——面向切面编程,Spring中的AOP编程

面向切面编程 AOP思想:将横向重复代码,纵向抽取出来 AOP体现--Filter AOP体现--拦截器 AOP体现--动态代理 Spring中实现AOP思想 原理:Spring可以为容器中管理的对象生成代理对象 代理分为动态代理和cglib代理: 动态代理(优先) 被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术,换句话说,就是代理对象和被代理要实现同一接口 cglib代理 第三方代理技术,cglib代理,可以对任何类生成代理,代理的原理是对目标对象进行继承代理,

MVC中的错误-友好的处理方法

转自:http://blog.csdn.net/lizhao1226/article/details/6367400 “/”应用程序中的服务器错误. 无法找到资源. 说明: HTTP 404.您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用.请检查以下 URL 并确保其拼写正确. 请求的 URL: /sdf 版本信息: Microsoft .NET Framework 版本:4.0.30319; ASP.NET 版本:4.0.30319.1 //---------

MVC中的错误过滤器无法拦截URL路径错误的解决办法

“/”应用程序中的服务器错误. 无法找到资源. 说明: HTTP 404.您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用.请检查以下 URL 并确保其拼写正确. 请求的 URL: /sdf 版本信息: Microsoft .NET Framework 版本:4.0.30319; ASP.NET 版本:4.0.30319.1 //--------------------------------------------------------------------

第一节: Timer的定时任务的复习、Quartz.Net的入门使用、Aop思想的体现

原文:第一节: Timer的定时任务的复习.Quartz.Net的入门使用.Aop思想的体现 一. 前奏-Timer类实现定时任务 在没有引入第三方开源的定时调度框架之前,我们处理一些简单的定时任务同时都是使用Timer类, DotNet中的Timer类有三个,分别位于不同的命名空间下,分别是: ①.位于System.Windows.Forms里,即定时器控件,不过多介绍了 ②.位于System.Threading.Timer类里 (重点介绍) ③.位于System.Timers.Timer类里