java:AOP面向切面编程简介(Spring)

点击上面  免费订阅本账号!

本公众号主要推送javaweb开发相关技术,基础知识点,同时会深入剖析复杂的问题,分享一些优秀的框架,大型项目经验,当今最流行的Javaweb技术,热点科技新闻,招聘信息,生活乐趣等等。点击上方的蓝字,这样您每天可以看到更多的java知识和资讯!完全是免费订阅,请放心关注。

 AOP这个词相信大家都没有接触太多过,但是实际上你们已经有所接触了,就在设计模式中。AOP所用的思想其实和设计模式是一样的,即在不修改原代码的情况下统一增加或者修改功能。还有,AOP大多用在spring里面,但是本文所写的只是在MVC中的应用,要注意。

一、简介

        所谓AOP(Aspect Oriented Programming的缩写)意为

面向切面的编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

        以上是百度百科的官方解释,但是在我看来,其实AOP更多的是一种思想,一种可以动一发而通全身的思想,AOP其实面对的更多是一种同意的功能或者调用过程来进行编写的一种程序体,从它的第一个词Aspect(切面)也就是指的一个方面,也可以了解到这种方式也就是针对一个方面的实现,这一点其实和mvc中的global文件很像,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

        其次就是它的预编译性质可以很好的处理一些错误或者是预先判断一些情况,这也导致了它在设计的时候在判断权限,统一输出某个东西方面变得比较常见。“可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。”上面这句话也是对于AOP的很好的诠释。

二、在MVC中的实现

        说了这么多了,让我们来实战一下吧,首先我们需要在vs新建一个mvc的项目,选择MVC3或者是4都OK,然后建立一个controller,命名随意,然后建立他的视图,在视图上写上最简单的HelloWorld。

  1. <!DOCTYPE html>  

  2.   

  3. <html>  

  4. <head>  

  5.     <title>Index</title>  

  6. </head>  

  7. <body>  

  8.     <div>  

  9.         <a>Hello! World</a>  

  10.     </div>  

  11. </body>  

  12. </html>  



        右图是我创建好的MVC解决方案和添加好的controller还有view,在view中写入上面的代码以显示Hello!World。

         运行之后(不会运行的自行百度)是不是就显示出了一个HelloWorld的字样在网页上呢?

         好,接下来我们开始新建AOP的一个文件然后去使用,首先在本项目中新添加一个类,名字叫FilterPublic,在引用的地方添加using  System.Web.Mvc这个引用,然后让这个类继承于ActionFilterAttribute,大家要注意Action这个词,说明这个东西是基于动作的。

        然后我们写入以下代码:

  1. public string Message { get; set; }  

  2.   

  3. public override void OnActionExecuting(ActionExecutingContext filterContext)  

  4. {  

  5.     base.OnActionExecuting(filterContext);  

  6.     filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");  

  7. }  

  8.   

  9. public override void OnActionExecuted(ActionExecutedContext filterContext)  

  10. {  

  11.     base.OnActionExecuted(filterContext);  

  12.     filterContext.HttpContext.Response.Write("Action执行之后" + Message + "<br />");  

  13. }  

  14.   

  15. public override void OnResultExecuting(ResultExecutingContext filterContext)  

  16. {  

  17.     base.OnResultExecuting(filterContext);  

  18.     filterContext.HttpContext.Response.Write("返回Result之前" + Message + "<br />");  

  19. }  

  20.   

  21. public override void OnResultExecuted(ResultExecutedContext filterContext)  

  22. {  

  23.     base.OnResultExecuted(filterContext);  

  24.     filterContext.HttpContext.Response.Write("返回Result之后" + Message + "<br />");  

  25. }  


        这个里面就是Filter触发的各种动作,然后我们在controller里面的默认方法做以下修改:

  1. [<span style="font-size:18px;">FilterPublic</span>(Message = "Action")]  

  2. public ActionResult Index()  

  3. {  

  4.     HttpContext.Response.Write("Action正在执行···<br />");  

  5.     return Content("正在返回Result···<br />");  

  6. }  

然后在controller的class类上面也添加一句[FilterPublic(Message = "Controller")],然后运行,会出现什么结果呢?

  1. Action执行之前Action  

  2. Action正在执行···  

  3. Action执行之后Action  

  4. 返回Result之前Action  

  5. 正在返回Result···  

  6. 返回Result之后Action  

        可以看到controller里面的方法在执行之前会去先执行以下我们设置的FilterPublic里面的代码,而且随着里面动作发生时间不同也可以看出了都是哪个方法被触发了。

        但是在controller上面写的基于controller的方法却没有触发,这是为什么呢?

         其实这个问题很简单,就是我们在设置我们的AOP程序的时候没有进行参数的设置,没有让filter进行叠加的运行,这个时候我们只要在写的FilterPublic类的上面加上:[AttributeUsage(AttributeTargets.All, AllowMultiple = true)],就可以让你设置的各种filter或者叠加的filter进行触发了,这个时候我们再运行一下试试:

  1. Action执行之前Controller  

  2. Action执行之前Action  

  3. Action正在执行···  

  4. Action执行之后Action  

  5. Action执行之后Controller  

  6.   

  7. 返回Result之前Controller  

  8. 返回Result之前Action  

  9. 正在返回Result···  

  10. 返回Result之后Action  

  11. 返回Result之后Controller  


       这样一来,在controller上的Filter也被触发了,所以我们使用AOP的方法只需要在我们自己的写的方法或者页面默认的加载方法上面写上一个filter类的标签就可以了。

       那么,如果我们有个功能需要所有的页面都触发,这样岂不是也很麻烦么?别担心,这个时候就轮到我们的global文件发挥作用了。在global.asax文件下面的RegisterGlobalFilters方法下面注册自己写的Filter就可以了:

  1. public static void RegisterGlobalFilters(GlobalFilterCollection filters)  

  2. {  

  3.     filters.Add(new HandleErrorAttribute());  

  4.     //把自己的filter定义成全局的filter  

  5.     filters.Add(new <span style="font-size:18px;">FilterPublic</span>() { Message = "全局<br/>" });  

  6.   

  7. }  


然后运行,看结果:

  1. Action执行之前全局  

  2.   

  3. Action执行之前Controller  

  4. Action执行之前Action  

  5. Action正在执行···  

  6. Action执行之后Action  

  7. Action执行之后Controller  

  8. Action执行之后全局  

  9.   

  10. 返回Result之前全局  

  11.   

  12. 返回Result之前Controller  

  13. 返回Result之前Action  

  14. 正在返回Result···  

  15. 返回Result之后Action  

  16. 返回Result之后Controller  

  17. 返回Result之后全局  


这样全局的触发也就做好了(filter中的message只是用于标识层级的,正式用的时候可以不用定义。)

        这样一看,如果想要快速的添加一个全局都用的方法,只需要新建一个Filter,然后再改一下global文件就可以办到了,是不是很方便呢。

    以上均为本人对于AOP的一些浅浅的研究,如有错误的地方还请读者指正。

原文地址:http://blog.csdn.net/tr1912/article/details/53679799

点击阅读全文阅读"Java中如何遍历Map对象的4种方法"

有人用微信聊天,有人却在微信中学习,成长。下面是2016最HOT IT公众号,赶快试试新的关注方法吧!


关注方式
★长按二维码,选择“识别图中二维码”进行关注。

 没看够?更多好文在阅读原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值