理解AOP思想(面向切面编程)
AOP:面向切面编程,相信很多刚接触这个词的同行都不是很明白什么,百度一下看到下面这几句话:
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
其实在这里谈起AOP也是为了总结一下自己这几年工作以来对Spring的一些新认识。再次声明一下,本文只记录个人最spring的见解记录,如有大神看到问题所在,请多指正一起学习。
大家都知道Spring是一个框架,但框架这个词对新手有点抽象,从功能的角度来定义它确实是一个框架,而从本质意义上来讲,Spring是一个库,一个Java库,所以我个人觉得应该这样回答Spring是什么:Spring是一个库,它的功能是提供了一个软件框架,这个框架目的是使软件之间的逻辑更加清晰,配置更灵活,实现这个目的的手段使用AOP和IOC,而AOP和IOC是一种思想,是一种什么样的思想等下细说,而AOP在Java里是利用反射机制实现(你也可以认为是动态代理,不过动态代理的本质也是反射机制实现的,所以还是先不要管动态代理,我们这里化繁为简,不让它干扰咱们对AOP的理解)
这里先说一下如何使用AOP:
其实AOP也并不是很复杂难懂,在我理解他只是简化开发的一种方式,举个例子:当我们在开发一套后台管理系统时必然有些操作在进行处理前先要验证操作人是否已经登陆。如果登陆还可能要判断这个用户对应的角色是否有当前操作的权限。这时,在每一步操作前可能就需要我们频繁处理这种权限验证问题。此时Spring就为我们制定了一种规范:AOP,如果把程序流程想象成管道,那么在一个系统中就很可能存在多条这样的管道。而在这多条管道中就有可能出现同样功能的代码段。AOP的实现其实就是把这些管道需要实现同样功能的代码段提取出来。就像一堆木头被切成两段那样,而这个切入口就被成为切面,每根木头被切断的地方就是切点。这样一来要比一根根去处理木头省事得多。
有了AOP,你写代码时不要把这个验证用户步骤写进去,即完全不考虑验证用户,你写完之后,再另外一个地方,写好验证用户的代码,然后告诉Spring你要把这段代码加到哪几个地方,Spring就会帮你加过去,而不要你自己Copy过去,如果你有多个控制流程,这个写代码的方法可以大大减少你的时间,不过AOP的目的不仅仅是这样,而是让我们在写代码的时候能够更多的去考虑主流程,而不用去考虑那些不太重要的枝节流程。
懂C的都知道,良好的风格要求在函数起始处验证参数,如果在C上可以用AOP,就可以先不管校验参数的问题,事后使用AOP就可以隔山打牛的给所有函数一次性加入校验代码,而你只需要写一次校验代码。不知道C的没关系,举一个通用的例子,经常在debug的时候要打log吧,你也可以写好主要代码之后,把打log的代码写到另一个单独的地方,然后命令AOP把你的代码加过去,注意AOP不会把代码加到源文件里,但是它会正确的影响最终的机器代码。
现在大概明白了AOP了吗,我们来理一下头绪,上面那个方框像不像个平面,你可以把它当块板子,这块板子插入一些控制流程,这块板子就可以当成是AOP中的一个切面。所以AOP的本质是在一系列纵向的控制流程中,把那些相同的子流程提取成一个横向的面,这句话应该好理解吧,我们把纵向流程画成一条直线,然把相同的部分以绿色突出,如下图左,而AOP相当于把相同的地方连一条横线。
如下图右,这个图没画好,大家明白意思就行。
这个验证用户这个子流程就成了一个条线,也可以理解成一个切面,aspect的意思我认为是方面,你用什么实物去类比,只要你能理解都可以。这里的切面只插了两三个流程,如果其它流程也需要这个子流程,也可以插到其它地方去。