首页 > 代码库 > Spring之AOP

Spring之AOP

本文来介绍Spring的AOP。


为什么使用AOP?

使用纯面向对象的思想进行编程。那么对象不但须要处理自身要负责的业务逻辑,要须要关心日志、安全控制和事务。例如以下图:

技术分享

                               图1


对遍布系统的关注点服务的调用,常常很分散。如日志和安全。


AOP使这些服务模块化,并以声明的方式将它们应用到它们须要影响的组件中去。结果使这些组件具有高内聚以及更加关注自身业务,全然不须要了解可能涉及的系统服务的复杂性。

所以:AOP确保POJO保持简单,AOP是OOP的最好的补充与完好。

利用AOP,我们能够使用各种功能层去包裹核心业务层。

这些层以声明的方式灵活应用到你的系统中,甚至你的核心应用根本不知道它们的存在。

这是一个很强大的理念,能够将安全、事务和日志关注点与核心业务分离。

例如以下图:

    技术分享

                          图2

利用AOP。遍布系统的关注点覆盖在它们所应用的组件之上。促使应用组件仅仅需关注它们的核心业务功能。


AOP

AOP有自己术语。虽然这些术语不是非常直接,可是我们要逐步了解它们。

技术分享


Cross Cutting Concern横切关注点

横切性关注点,就是要动态运行的方法,它会遍布在系统的处理流程中。

Aspect切面

对横切性关注点的模块化。

且面试通知和切点的结合。通知和切点共同定义了关于切面的所有内容——它是什么。在何时何处完毕其功能。


Advice通知

对横切性关注点的详细实现。通知定义了切面是什么,以及何时使用。此外,通知还决定了什么时候运行工作的问题。是在应用某个方法被调用之前(Before)、之后(After)、成功运行后(After-returning)、异常(After-throwing)和Around(被通知的方法调用前后)。


JoinPoint连接点

Advice在应用程序上运行的点或时机。Spring仅仅支持方法的连接。这个点也能够使属性改动。如Aspectj

连接点是应用运行过程中鞥能够插入切面的一个点。这个店能够使调用方法时、抛出异常时、甚至改动一个字段时。切面代码能够利用这些点插入到应用的正常流程之中,并加入新的行为。这些操作,都在编译前完毕。

Pointcut切点

定义了Advice应用到哪些连接点上,对Spring来说就是方法调用。切面定义了“什么”和“何时”,切点定义了“何处”。

切点的定义会匹配同志全部织入的一个或多个连接点。我们通常使用明白的类和方法名称来指定这些切点。或是利用正则匹配类和方法名称模式来指定这些切点。有些AOP框架同意我们动态的切点,能够依据执行时的决策(如方法的參数值)来决定是否应用通知。

Weave织入

将Advice应用到Target Object的过程。

Spring支持动态织入。

在目标对象的生命周期里多个点能够进行织入:

   编译期——切面在目标类编译时被织入。

AspectJ的织入就是这样的方式;

   类载入期——切面在目标类载入到JVM时被织入。这样的方式须要ClassLoader,能够再目标类被引入应用之前增强目标类的字节码。

   执行期——切面在应用执行的某个时刻被织入。

在织入切面时,AOP容器会为目标对象动态创建一个代理对象。这是Spring AOP的织入方式

Proxy

Spring的AOP默认使用JDK的动态代理,它的代理是执行时创建的。也能够使用CGLIB代理。

Introduction

能够动态的为类加入方法。


Spring的AOP

眼下AOP已经形成了三足鼎立。

AspectJ、Jboss AOP和Spring的AOP。

这里,我们注重介绍Spring的AOP。

Spring仅仅支持方法连接点。应为Spring基于动态代理,所以Spring仅仅支持方法连接点。

而AspectJ和JBoss的AOP,除了方法切点。还提供了字段和构造器接入点。Spring缺少对字段连接点的支持。

无法让我们创建细粒度的通知。

因为。SpringAOP对方法的支持,就已经足够了。假设还不能满足,能够考虑使用AspectJ来辅助实现。这里。我们重点介绍动态代理方式的AOP。


AOP的内部实现

Spring的AOP默认使用JDK的动态代理,同一时候。也支持CGLIB的代理。

JDK动态代理。採用反射机制动态创建的。动态生成了字节码。仅仅是他生成的字节码的方式必须和接口绑定。

JDK动态代理源代码剖析:JDK动态代理实现原理


JDK的动态代理有非常大限制。这样的方法要求业务类必须实现一个业务接口。

即。仅仅有以下情况,才干使用JDK的动态代理:

             技术分享

而CGlib引用第三方包asm.jar,採用字节码技术。

通过字节码技术为须要代理的类创建一个子类,并在子类中採用方法拦截的技术拦截全部父类方法的调用,并织入横切逻辑。

CGlib採用继承的方式,继承指定的类。对指定的类生成一个子类。覆盖其全部方法。

这样的方式,不管有无接口。都可以对其进行代理。如以下两种情况:

     技术分享


CGLIB创建动态代理对象性能比JDK创建的动态代理对象性能高非常多,可是CGLIB在创建代理对象时所花费的时间却比JDK多非常多。所以对于单例的对象,无需频繁的创建对象,使用CGlib比較合适;则反,假设须要频繁创建对象,考虑使用JDK代理。


本文总结了Spring中AOP的相关内容、AOP的相关术语以及内部实现。

详细实现就不往外贴了,比較简单。

有兴趣的童鞋能够在以下留言,一起讨论一下。

Spring之AOP