AOP(Aspect-Oriented Programming,面向切面的编程),谈起AOP,则必定会追溯到OOP(Object Oriented Programming,面向对象编程),由于AOP能够说是对OOP的补充和完善,而这一切的理念都是从模块化开始的。OOP是一种很是成功、极具表现力的编程范式,它将概念天然地表达为对象,从而将其中通用的代码模块化。因此,衡量OOP成功与否的标准就是它在多大程度上避免了代码的重复。通常状况下,OOP可以很好地避免代码重复。具体继承能够帮助咱们在不一样类型之间共享相同的行为;多态让咱们能够用一样的方式来处理不一样类型之间的对象,可以让咱们将注意力集中在他们的共同之处。但当赶上一些特定问题的时候,好比,当咱们须要为分散的对象引入公共行为时,OOP就显得很无力了。也就是说,OOP很适合你定义从上到下的关系,但不适合定义水平的关系。能够说由于有这些Bug的存在,是AOP生成的直接诱因,因此是为了弥补OOP而存在的。AOP在看待应用程序结构的方式上与OOP是大相径庭的,以AOP的思路来看,系统是被分解成方面(Aspect)或者关注点(Concern),而不是一个个对象。追根溯源,与OOP同样,AOP只不过是一种全新的模块化机制而已,他的主要做用是用来描述分散在对象、类或函数中的横切关注点,从关注点中分离出横切关注点则是 AOP的核心概念。正则表达式
AOP的原理,也是很是简单的,即经过分离关注点让解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中就再也不含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系则经过切面来封装、维护,这样本来分散在整个应用程序中的代码就能够很好的进行管理了。例如:在使用公共函数的时候,每每须要进行一些逻辑设计,也就时须要代码实现来支持,而这些逻辑代码也是须要维护的,在传统的公共子模块的调用中,除了直接调用之外就没有其余的手段。而相同的状况,在使用AOP后,不只能够将这些重复的代码抽出来单独维护,并且能够在须要时进行统一调度,这样的使用方法虽然与设计公共子模块有几分类似,但他为这一类问题的解决提供了一整套完整的理论和灵活多样的实现方法。也就是说,在AOP提出横切概念之后,再把模块功能正交化的同时,也在此基础上提供了一系列横切的灵活实现。编程
在编译期修改源代码、运行期字节码加载前修改字节码或字节码加载后动态建立代理类的字节码,这是AOP的具体实现方法,而他是由三个重要步骤来完成的,先是生成代理对象,而后是拦截器的做用,最后是编织的具体实现。AOP框架的丰富,其实很大程度上体如今这三个步骤上所具备的丰富技术选择,以及与IOC容器之间的无缝缝合。而若是以实现方法来分的话,则主要有两类:静态AOP(包括静态织入)和动态AOP(包含动态代理、动态字节码生成、自定义类加载器、字节码转换器)。
缓存
除了经过使用Proxy代理对象、拦截器字节码翻译技术等一系列已有的AOP或者AOP实现技术,来实现切面应用的各类编织实现和环绕加强之外。还成立了AOP联盟来探索AOP的标准化,但愿借此来推进AOP的发展。而对于如今已有的AOP实现方案,AOP联盟对它们进行了必定程度的抽象,从而定义出了AOP的体系结构。结合这个AOP体系结构去了解AOP技术是很是有帮助的,AOP联盟定义的AOP体系结构如图所示:性能优化
AOP联盟定义的AOP体系结构把与AOP相关的概念大体分为由高到低、从使用到实现的三个层次。从上往下:框架
最高层是语言和开发环境,在这个环境中能够看到几个重要的概念:“基础”能够视为待加强对象或者说目标对象;“切面”一般包含对于基础的加强应用;“配置”能够当作是一种编织,经过在AOP体系中提供这个配置环境,能够把基础和切面结合起来,从而完成切面对目标对象的编织实现。
模块化
AOP体系结构的第二层次为语言和开发环境提供支持的,在这个层次中能够看到AOP框架的高层实现,主要包括配置和编织实现两部份内容。例如配置逻辑和编织逻辑实现自己,以及对这些实现进行抽象的一些高层API封装。这些实现和API封装,为前面提到的语言和开发环境的实现提供了有力的支持。
函数
最底层是编织的具体实现模块,各类技术均可以做为编织逻辑的具体实现方法,好比反射、程序预处理、拦截器框架、类装载器框架、元数据处理等等。性能
AOP在 权限(Authentication)、缓存(Cache)、内容传递(Context passing)、错误处理(Error handling)、懒加载(Lazy loading)、调试(Debug)、日志(Log)、跟踪优化和校准(tracing、profiling and monitoring)、性能优化(Performance optimization)、持久化(Persistence)、资源池(Resource pooling)、同步(Synchronization)、事务(Transactions)等方面都有用处,能够说是可以使用范围及广。下面咱们就以一张思惟导图来串联,以此来铺开与AOP相关的全部的知识点。优化
AOP一般包含如下相关术语:
spa
一、目标对象(Target):包含链接点的对象。也被用来引用加强化或代理化对象。
二、代理(Proxy):AOP 框架建立的对象,包含加强。
三、链接点(Joinpoint):程序执行过程当中明确的点,如方法的调用或特定的异常被抛出。
四、切点(Pointcut):指定一个通知将被引起的一系列链接点。AOP 框架必须容许开发者指定切入点:例如,使用正则表达式。
五、加强(Advice):在特定的链接点AOP框架执行的动做。各类类型的加强包括“around”、“before”、“throws”加强等等。加强类型将在下面讨论。许多 AOP 框架都是以拦截器作加强模型,维护一个“围绕”链接点的拦截器链。
六、切面(Advisor):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事物管理是J2EE应用中横切关注点中一个很好的例子。切面通常是用 Advisor 或者 拦截器实现。
七、织入(Weaving):组装方面建立通知化对象。这能够在编译时完成(例如:使用AspectJ编译器),也能够在运行时完成。Spring 和其余一些纯 Java AOP 框架,使用运行时织入。
八、引入(Introduction):添加方法或字段到加强化类。
九、接口(IsModified):用于简化缓存。(这里做为补充)。
AOP加强类型(也叫 通知类型)包括:
一、Before Advice(前置加强):在一个链接点以前执行的加强,但这个加强不能阻止流程继续执行到链接点(除非它抛出一个异常)。
二、After Advice(后置加强,全称是 After returning advice 正常返回加强 ):在链接点正常完成后执行的加强,例如,若是一个正常返回,没有抛出异常。若是抛出异常则不会执行。
三、Around Advice(环绕加强):包围一个链接点的加强,如方法调用,是最强大的加强。在方法调用先后完成自定义的行为。它们负责选择继续执行链接点或直接返回它们本身的返回值或抛出异常来执行。
四、Throws Advice(抛出加强,全称是 After throwing advice 异常返回加强,也叫 Finally returning advice 最终返回加强):是最经常使用的加强类型。大部分是基于拦截器框架如Nanning或者JBoss4提供的Around加强。做用是,无论,是否正常执行,都会返回加强中的内容。
五、Introduction Advice(引入加强):一种很是特殊的加强。它将新的成员变量、成员方法引入到目标类中。它仅能做用于类层次,而不是方法层次,因此他不能做用于任何切入点。
AOP模块是Spring的核心模块,尽管Spring中有本身的一套AOP实现,但在Java社区中是最完整AOP框架仍是Aspectj,因此为了弥补本身的不足,也为了提供更加丰富的AOP解决方案,Spring对Aspectj作了集成。同时,再配合Spring的IOC容器,Spring推出了一个完善的AOP解决方法。
Spring AOP的核心技术是JDK的动态代理技术。Spring AOP是以动态代理技术为基础,设计出了一系列AOP的横切实现,好比:前置加强、返回加强、异常加强等等。同时,Spring AOP还提供了一系列的Pointcut来匹配切入点,可使用现有的切入点来设计横切面,也能够扩展相关的Pointcut方法来切入需求。
在Spring AOP 中,咱们通常是经过配置文件或者编程的方式来实现的。常见的配置方法有四种:1,配置 ProxyFactoryBean 显示设置 advisors、advice、target 等。2,配置 AutoProxyCreator 这种方式下,仍是如之前同样定义 bean,可是从容器中得到的实际上是代理对象。3,配置 <aop:config>。4,配置 <aop:aspectj-autoproxy>,使用 AspectJ 的注解来表示以前以及切入点。而编程方式是直接经过 ProxyFactory 设置 target 对象,再经过 getProxy 方法来获取代理对象。
总的来讲,在Spring AOP中,对于AOP的使用者来讲,可能简单配置 Bean 便可,但仔细分析 Spring AOP 的内部设计就能够看到,为了让AOP起做用,须要参照前面的 AOP 实现原理来完成一系列过程,须要为目标对象创建代理对象,这个代理对象能够经过使用JDK的Proxy来完成,也能够经过第三方的类生成器CGLIB来完成。而后,还须要启动代理对象的拦截器来完成各类横切面的织入,这一系列的织入设计时经过一系列 Adapter 来实现的。经过一系列 Adapter 的设计,就能够把AOP的横切面设计和Proxy模式有机地结合起来,从而实如今 AOP 中定义各类织入方式(这里的源码部分可能不会涉及)。具体实现过程笔者会在后面的文章中详细阐述。
——水门(2016年3月于杭州)