什么是AOP
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版本通过动静代理实现,动静代理咱们也很相熟,后面专门剖析过,是在运行期动静生成指标类的代理对象的,无非两种形式:
- JDK动静代理,基于接口实现。
- Cglib动静代理,生成指标类的扩大类实现。
具体请参考动静代理 java原生 vs Cglib
所以咱们当初应该明确,AOP是什么,为什么会有AOP,以及AOP的底层原理。
AOP术语
我始终在想,对于AOP的初学者,是通过间接上手练习的形式入门,还是依照惯例的形式:先学习AOP的实践,把握AOP的概念和术语,而后再通过简略示例增强了解。
惯例学习路线应该是后者,然而,尽管AOP的概念和底层逻辑很好了解,然而AOP的术语却极具迷惑性、十分不敌对,很难了解。
然而的确没有方法,要学习AOP,那么AOP的术语就是迈不过来的一道坎,无论如何也是要有所理解的。
所以,来吧,看看AOP相干术语,咱们尽量用简单明了的语言来解释。
- Target object: 指标对象,指的就是咱们的业务对象,咱们要通过AOP技术加强指标对象的办法(对于Spring Aop来说,只加强指标对象的办法,对于AOP联盟来说,还能够加强属性)。
- AOP proxy:AOP代理对象,后面曾经说过AOP的底层逻辑就是通过代理实现的,AOP proxy指的就是指标对象的代理对象。
- Join point:连接点,其实是AOP要加强的点,对于Spring AOP来说,咱们要加强的其实就是指标对象的办法执行过程,所以连接点就是办法执行。
- Pointcut:切点,指的是满足条件的连接点,或者能够了解为满足切入连接点的条件。切点通过表达式的形式定义条件,满足切点条件的时候,执行切入动作、加强连接点规定的办法。
- Advice:加强逻辑,是AOP要实现的目标的体现,比方实现事务管理的AOP,Advice就是开启及提交或回滚事务,日志解决的AOP,Advice就是在连接点办法执行前后打印日志。
- Aspect: 切面,简略说就是体现连接点Join point定义、Pointcut定义、以及Advice逻辑实现的模块(能够简略了解为:一组类)。Spring Aop中通过xml配置文件指定、或者通过注解@Aspect指定。
- Introduction:推荐(其实不翻译最好,AOP的这些术语其实都是这样,不翻译、直呼其英文名最好),能够这么了解:AOP切面类中,除为了实现目标类办法加强之外,还能够定义其余的属性或办法,去帮忙实现AOP之外的额定的性能。
- Weaving:织入,就是依据Aspect的定义,对符合条件的指标对象,通过动静代理技术加强其办法逻辑、生成代理对象的过程。生成代理对象之后,就相当于咱们把Advice“织入”到代理对象中了。
Spring AOP的Advice类型:
- Before advice:在join point执行前失效,然而advice没有拦挡阻止join point的能力,起因是Spring Aop的Before advice对指标对象的join point的调用控制权并不在切面类中,而是交给了框架,所以除非有异样产生、否则无奈拦挡或阻止join point办法的执行。
- After returning advice: join point失常执行实现并返回后失效。
- After throwing advice: join point调用异样后失效。
- After (finally) advice: join point调用后失效,不论失常完结或抛出异样。
- Around advice: Spring AOP性能最为弱小的advice,功能强大的起因是:对join point的调用是在切面实现的,所以,切面编写者有权对join point调用前、调用后的逻辑做全面的管制,比方能够在调用前进行逻辑判断后阻止join point的调用,返回后面自定义的返回值或者抛出异样,也能够在join point调用后依据其返回值做任意的解决。
既然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 vs AspectJ
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反对的连接点的区别:
上一篇 Spring FrameWork从入门到NB - ApplicationContext