首页 > 代码库 > Spring之AOP

Spring之AOP

---------------siwuxie095

   

   

   

   

   

   

什么是 AOP

   

   

  • AOP 的基本概念

       

    AOP,即 Aspect Oriented Programming,面向切面编程,

    通过 预编译方式 运行期动态代理 实现程序功能的统一维护

    的一种技术

       

    AOP 是一种比较新颖的设计思想,同时也是 Spring 框架中

    一个非常重要的内容

       

       

    AOP 将应用系统分为两个部分:

       

    核心业务逻辑 以及 横向的通用逻辑,即 所谓的方面(切面)

       

    如:所有大中型应用都要涉及到的持久化管理、事务管理、安全管理、

    日志管理 以及 调试管理

       

       

    Spring 中,提供了面向切面编程丰富的支持:

       

    允许通过分离 应用的业务逻辑 系统级的服务,进行内聚性的开发。

    应用对象只实现它们应该做的,即 完成业务逻辑,仅此而已。它们并

    不负责,甚至不会意识到系统级别的关注点,如:日志 事务支持

       

       

       

  • AOP OOP 的关系

       

    AOP 是对 OOP 面向对象编程的一种有益的补充,同时,AOP 也是 OOP 的延续

       

       

    面向对象编程 OOP:

       

    从静态角度考虑程序结构,即 OOP 对业务处理过程中的

    实体以及属性和行为进行了抽象的封装,以获得更加清晰、

    高效果的逻辑划分,研究的是一种静态的领域

       

       

    面向切面编程 AOP:

       

    从动态角度考虑程序运行过程,即 是针对业务处理过程中的

    切面进行提取,它所面对的是处理过程中的某个步骤 或阶段,

    研究的是一种动态的领域

       

       

       

  • AOP 的主要功能

       

    主要是用于系统级别的功能,如:日志记录、性能统计、

    安全控制、事务处理、异常处理

       

       

       

  • AOP 的主要意图

       

    AOP 主要是将日志记录、性能统计、安全控制、事务处理、异常处理

    代码从 业务逻辑代码 中划分出来

       

    通过对这些行为的分离,希望可以将它们独立到 非指导性业务逻辑方法 中,

    进而改变这些行为时,不影响 业务逻辑代码 的处理

       

    即 AOP 把一些常用的服务进行模块化,并且用声明的方式将这些组件使用

    到其他的业务组件中去

       

    这样做的结果就是每一个业务组件只需要关心自己的业务逻辑,而不用去了解

    一些常用的服务组件,保证了更高的内聚性

       

    使用 AOP 可以将处理切面等代码注入程序,通常主程序的主要目的并不在于

    处理这些切面的功能,所以 AOP 可以有效的防止代码混乱

       

    Spring Framework 的 AOP 作为一种非侵略性的轻型的 AOP Framework,

    无须使用预编译器,或其它元标签,便可以在 Java 程序中使用,这意味着开

    发团队中只需要有一个人来应对 AOP Framework,其他人还可以像往常一样

    进行业务逻辑的编程

       

       

       

       

       

       

    AOP 的存在价值

       

       

    AOP 专门用于处理系统中分布于各个模块中的交叉关注点的问题,

    在 Java EE 应用中,常常通过 AOP 来处理一些具有横切性质的系

    统级服务,如:事务管理、安全检查、缓存、对象池管理等,AOP

    已经成为一种非常常用的解决方案

       

       

       

    为什么要使用 AOP 呢?

       

    是因为系统有很多不同的组件,每一个组件负责一块特定的功能,我们希望

    每一个组件只关心它自身的核心功能,但在系统中会有一些组件,如:日志

    模块、事务管理模块和安全模块这些组件会比较频繁的融入到其他核心业

    务逻辑组件当中去

       

    这些常用组件分散到其他多个组件中,会带来麻烦:

       

    1)如果这些常用的服务组件经常发生变化,那么需要在多个

    其他组件中进行相应地修改

       

    2)这样使得组件代码因为插入了与自身核心业务无关的服务

    组件而变的很混乱

       

       

    为了更好的说明为什么要使用 AOP,看如下实例:

       

    如下图所示,假设系统中有三段完全相似的代码,这些代码通常使用

    复制、粘贴的方式来完成。通过这种复制,粘贴方式所开发出来的软

    件就像这幅图所描述的一样

       

    技术分享

       

       

    它的不足之处是:如果有一天图中深色代码需要修改,就要打开三个地方

    进行修改。那如果是一百个、一千个地方,后果可想而知

       

       

       

    为了解决这个问题,通常会将深色代码定义为一个方法,然后在三个地方

    分别调用该方法即可,在这种方式下,软件系统的结构如下图所示

       

    技术分享

       

       

    对于上图所示的系统,如果需要修改深色代码,只要修改一个地方即可,

    通过这种方式就大大降低了软件后期维护的复杂度

       

    对于其中的三个方法,当前依然需要显式调用,这样做能够解决大部分

    的应用场景

       

       

    但对于一些更特殊的情况,应用需要三个方法彻底与深色方法相分离,

    该如何解决呢?

       

    因为软件需求变更是很频繁的事情,系统前期设计的三个方法,只实现了

    核心业务的功能。过了一段时间,需要为三个方法增加事务控制,又过了

    一段时间,客户提出三个方法需要用户合法性验证,只有合法用户才能执

    行这些方法

       

    面对这样的情况,该怎么办?通常有两种做法:

    1)根据需求说明书,直接拒绝客户要求

    2)拥抱需求,满足客户的需求

       

    第一种做法显然不好,客户是上帝,应该尽量满足客户的需求。通常采用

    第二种做法,那么如何解决?不可能每次都定义一个新的方法,然后修改

    三个方法,增加新调用的方法,这样的工作量太大

       

    希望有一种特殊的方法,只要定义了该方法,无需在三个方法中显式调用,

    系统就会自动执行这些特殊的方法

       

    上面的方法听起来很神奇,甚至有些不切实际,其实是完全可以实现的,

    实现该需求的技术正是 AOP

       

       

       

       

       

       

    AOP 的原理剖析

       

       

    AOP 代理其实是由 AOP 框架动态生成的一个对象,该对象可作为目标对象使用

       

    AOP 代理所包含的方法与目标对象的方法如下图所示:

       

    技术分享

       

       

    AOP 实际上是由目标类的代理类实现的,AOP 代理其实是由 AOP 框架

    动态生成的一个对象,该对象可以作为目标对象使用,AOP 代理包含了

    目标对象的全部方法

       

    AOP 代理的方法与目标对象的方法存在着差异:

       

    AOP 方法在特定侵入点添加了增强处理,并回调了目标对象的方法

       

       

    纵观 AOP 编程,其中程序员参与的只有三个部分:

    1)定义普通业务组件

    2)定义切入点:一个切入点可能会横切多个业务组件

    3)定义增强处理:增强处理就是在 AOP 框架为普通业务组件置入的处理动作

     

       

    AOP 编程的关键:定义切入点 定义增强处理

       

    一旦定义了合适的 切入点 增强处理,AOP 框架将会自动生成 AOP 代理

       

       

    AOP 代理的方法有如下的公式:

       

    代理对象的方法 = 增强处理 + 被代理对象的方法

       

       

    在上面的业务定义中不难发现,Spring AOP 的实现原理其实很简单:

       

    AOP 框架负责动态生成 AOP 代理类,这个代理类的方法则由 增强处理

    回调目标对象的方法 组成

       

       

       

       

       

       

    AOP 的关键概念

       

       

    以下是官方文档所给出的 AOP 关键概念的解释:

       

    1)切面 - Aspect

       

    切面是一个关注点的模块化,这个关注点可能会横切多个对象。事务

    管理是 J2EE 应用中一个关于横切关注点的很好的例子

       

    Spring AOP 中,切面可以基于模式 或基于 Aspect 注解方式实现。

    通俗的说:即 加入的切面类,如:通常所说的日志类

       

       

    2)连接点 - Join Point

       

    连接点是在程序执行过程中的某个特定的点,

    如:某方法调用的时候,或处理异常的时候

       

    Spring AOP 过程中,一个连接点总是表示一个

    方法的执行。通俗的说:即 加入切点的那个点

       

       

    3)通知 - Advice

       

    通知是在切面的某个特定连接点上所执行的动作,其中包括

    around、before after 等不同类型的通知

       

    许多 AOP 的框架都是以拦截器作为通知模型,并且维护一个

    以连接点为中心的拦截器链

       

       

    4)切入点 - Point Cut

       

    切入点是匹配连接点的断言。通知和一个切入点表达式并联,

    并在满足这个切入点的连接点上运行

       

    切入点表达式如何和连接点匹配,是 AOP 的核心

       

    Spring 缺省(默认)使用 AspectJ 切入点语法

       

       

    5)引入 - Introduction

       

    引入是用来给一个类型声明额外的方法和属性

       

    Spring 允许引入新的接口到任何被代理的对象,如:可以使用

    引入来使一个 Bean 实现 isModify 的接口,以便简化缓存机制

       

       

    6)目标对象 - Target Object

       

    目标对象就是被一个 或多个切面所通知的对象,

    也被称作 被通知对象

       

    既然 Spring AOP 是通过运行时代理实现的,

    那么这个对象永远是一个被代理对象

       

       

    7)AOP 代理 - AOP Proxy

       

    AOP 代理其实就是 AOP 框架创建的对象,用来实现切面契约

       

    Spring 中,AOP 代理可以是 JDK 动态代理 CGLIB 代理

       

       

    8)织入 - Weaving

       

    织入就是把切面连接到 其他应用程序类型 或对象之上,并

    创建一个被通知的对象,这些可以在 编译的时候、类加载

    的时候、或运行的时候 完成

       

    Spring 和其他的纯 Java AOP 框架一样,在运行的时候来完成织入

       

       

       

       

       

       

    AOP 的通俗理解

       

       

    一个组件 A,不关心其他常用的服务组件 B,但组件 A 使用组件 B 时,

    不是组件 A 自身去调用,而是通过配置等其他方式,如:Spring 中可

    以通过 XML 配置文件

       

    这样就使得组件 A 压根就不需要知道服务组件 B 是怎样的,爱存在不存在,

    爱怎么存在都与组件 A 无关

       

    A 只关心自己的业务逻辑,具体当 A 使用 B 时,都是通过配置文件去做,与 A 无关

       

       

       

       

       

       

       

    【made by siwuxie095】

Spring之AOP