AOP - Aspect Oriented Programming的缩写,面向切面编程。
面向切面编程AOP是面向对象程序设计OOP的一个补充或扩展,是为了解决OOP在一些共性问题上的不足应运而生的。比如记录日志、事务处理、性能分析等等与业务无关的需求,需要发生在很多类的很多方法上,而需求是一样的:比如日志处理就是在方法执行前或执行后记录日志,事务处理需要在方法执行前开启事务、在方法执行结束后提交或回滚事务。
AOP出现之前,老程序员应该都有记忆(亲身经历),我们需要在每一个需要事务处理的方法中都添加逻辑一模一样的代码:获取连接、开启事务。然后在方法执行完成后也需要添加一模一样的代码:如果方法执行成功则提交事务、执行失败或发生异常则回滚事务。
这些代码写多了(其实不可能少、肯定会很多),能让程序员痛苦不堪、怀疑人生!
然后,AOP横空出世。
AOP其实最终要实现的功能就是:不侵入代码的前提下,实现上述这些公共逻辑。
我艹,简直不要太爽…
当然,横空出世的不是Spring AOP,那个时候还没有Spring。AOP横空出世之后,为了统一AOP的概念、属于以及接口,出现了AOP联盟,Spring AOP也遵循AOP联盟的相关规范。之后,AOP江湖逐渐被AspectJ统治,Spring从2.0开始就无缝集成了AspectJ。
AOP的底层逻辑其实不复杂,就是通过代理:需要实现这些公共逻辑的类,我们可以称之为目标类,不修改目标类、却要改变(或者叫增强)其执行逻辑,用脚指头都能想到是通过代理。
AOP的早期版本(AspectJ 1.0)通过静态代理实现,静态代理是在编译期修改目标类代码、生成代理类代码的方式,运行会比较快(因为在编译器就生成代理对象代码了),但是明显的缺点就是稍有修改就需要重新编译打包,不可谓不繁琐。
之后的AOP版本通过动态代理实现,动态代理我们也很熟悉,前面专门分析过,是在运行期动态生成目标类的代理对象的,无非两种方式:
所以我们现在应该明白,AOP是什么,为什么会有AOP,以及AOP的底层原理。
我一直在想,对于AOP的初学者,是通过直接上手练习的方式入门,还是按照常规的方式:先学习AOP的理论,掌握AOP的概念和术语,然后再通过简单示例加强理解。
常规学习路线应该是后者,然而,虽然AOP的概念和底层逻辑很好理解,但是AOP的术语却极具迷惑性、非常不友好,很难理解。
但是确实没有办法,要学习AOP,那么AOP的术语就是迈不过去的一道坎,无论如何也是要有所了解的。
所以,来吧,看看AOP相关术语,我们尽量用简单明了的语言来解释。
Spring AOP的Advice类型:
既然Around advice可以对join point做调用前、调用后的增强,而且其功能最为强大,那是不是就意味着before和after增强就没有存在的意义了呢?有关这一点,Spring官网其实也给出了一些建议:
Around advice is the most general kind of advice. Since Spring AOP, like AspectJ, provides a full range of advice types, we recommend that you use the least powerful advice type that can implement the required behavior. For example, if you need only to update a cache with the return value of a method, you are better off implementing an after returning advice than an around advice, although an around advice can accomplish the same thing. Using the most specific advice type provides a simpler programming model with less potential for errors. For example, you do not need to invoke the proceed() method on the JoinPoint used for around advice, and, hence, you cannot fail to invoke it.
一句话:选择刚好能满足自己需求的Advice、而不建议选择功能远超出自己需求的Advice,一方面简化切面逻辑,另一方面,减少调用错误的发生概率。
Spring AOP仅支持对方法的切入,而AspectJ支持属性切入。
有关Spring AOP的能力和目标,其实Spring官网有专门的说明:
Spring AOP’s approach to AOP differs from that of most other AOP frameworks. The aim is not to provide the most complete AOP implementation (although Spring AOP is quite capable). Rather, the aim is to provide a close integration between AOP implementation and Spring IoC, to help solve common problems in enterprise applications.
Spring AOP与大部分的AOP框架不同,Spring AOP的目标并不是提供一个功能强大的AOP实现(虽然说Spring AOP已经比较强大了)。反而,Spring AOP的髰提供一个将AOP和Spring IoC紧密集成的框架从而对企业级应用的开发提供帮助。
Thus, for example, the Spring Framework’s AOP functionality is normally used in conjunction with the Spring IoC container. Aspects are configured by using normal bean definition syntax (although this allows powerful “auto-proxying” capabilities). This is a crucial difference from other AOP implementations. You cannot do some things easily or efficiently with Spring AOP, such as advise very fine-grained objects (typically, domain objects). AspectJ is the best choice in such cases. However, our experience is that Spring AOP provides an excellent solution to most problems in enterprise Java applications that are amenable to AOP.
Spring AOP的功能通常可以通过Spring Ioc容器提供,切面可以通过正常的bean definition完成配置,这是与其他AOP框架的显著不同点。我们不太容易通过Spring框架实现细粒度的AOP控制。如果你有这样的需求,AspectJ是更好的选择。其实,Spring AOP已经可以解决企业应用开发中碰到的绝大部分AOP相关的问题。
Spring AOP never strives to compete with AspectJ to provide a comprehensive AOP solution. We believe that both proxy-based frameworks such as Spring AOP and full-blown frameworks such as AspectJ are valuable and that they are complementary, rather than in competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance API. Spring AOP remains backward-compatible. See the following chapter for a discussion of the Spring AOP APIs.
Spring AOP从来没想与AspectJ竞争、去提供一个强大的AOP解决方案。我们相信基于代理的框架比如Spring AOP、以及全功能的框架比如AspectJ,都是有价值的,是互补的关系,而不是竞争的关系。Spring框架很好的继承了Spring Aop、Spring IoC、以及AspectJ,从而使用户可以在Spring框架下、基于Spring框架来使用Aop。这种集成并没有影响Spring Aop API以及AOP联盟的API,Spring AOP确保向下兼容。
Spring AOP与AspectJ支持的连接点的区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o98KrtzO-1688996815295)(/img/bVc8IWb)]
上一篇 Spring FrameWork从入门到NB - ApplicationContext