前文的一些内容更多是针对Spring容器内部的一些特性的描述,接下来一个专题将描述Spring AOP的一些信息,配置细节等等。

介绍

面向切面编程(AOP)是一种新的针对程序结构的思路,它补足了面向对象编程(OOP)的一些细节上的不足。OOP的关键在于模块化概念,也就是Java中的class。而AOP关心的模块则是切面。切面关心的模块化主要是考虑的是诸如事物管理这类会跨越多个类型和对象的一些方面。(而这些类型对象通常是在多个不同业务层的。)

Spring的其中一个核心组件也就是AOP框架。而Spring IoC容器并不依赖AOP,也就是说,开发者如果不想使用AOP,就可以不使用AOP,AOP以一种中间件的方式补足了Spring IoC的功能。

Spring 2.0 AOP

Spring 2.0引入了一种既简单又有效的方式来支持定制切面,无论是使用基于契约(XML)的方式,还是基于@AspectJ注解的方式。两种方式都是支持AOP的全部功能的。

之后的AOP系列会将针对两种方式分别讨论。Spring 2.0 AOP是完全兼容之前的Spring 1.2 AOP的。后续AOP系列也会讨论AOP的相关API。

AOP在Spring框架中起的作用主要有两点:

  • 提供显式声明的企业服务,尤其是用来替换EJB服务的情况。其中最重要的服务就是诸如事务管理之类的服务。
  • 允许用户来实现定制的切面,使用AOP来补足OOP的不足。

AOP 基本概念

首先,我们来看下AOP的核心概念以及相关术语。这些术语并不是Spring特有的。很可惜的是,AOP的术语不是很直观,尤其是在Spring使用它自己的术语的时候很令人疑惑。

  • Aspect:一个横切多个类的模块化的服务。事物管理就是一个很好的例子,在企业应用当中,他会跨越很多的模块。在Spring的AOP中,切面是通过一般的类来实现(基于契约的方式)或者通过注解了@Aspect注解的一般类来实现(@AspectJ方式)。
  • JoinPoint:程序的一个执行点,比如一个方法的执行,或者是处理一个异常。在Spring AOP中,JoinPoint总是代表折方法的执行过程。
  • Advice:JoinPoint过程中的一些动作。包括aroundbefore以及after这几种类型的Advide。很多的AOP框架,包括Spring,都会将Advide作为一个interceptor(拦截器),保证在一个JoinPoint有一个拦截链。
  • Pointcut:判定是否匹配JoinPoint,Advide是和Pointcut表达式关联的,只有在Pointcut匹配的时候,才会运行在JoinPoint上面(举例来说,匹配一个方法的名字)。JoinPoint的概念和Pointcut表达式匹配是AOP中最重要的概念,默认情况下,Spring使用AspectJ的Pointcut表达式语言。
  • Introduction:声明额外的方法或者私有变量来代表一个类型。Spring AOP允许开发者来引入新的接口(以及对应的实现类)到切面对象上。举例来说,开发者可以通过使用Introduction,令Bean来实现IsModified接口,来简化缓存(Introduction作为AspectJ中的内在声明类型)。
  • TargetObject:由切面切入的对象就是TargetObject。也称之为advised对象。因为Spring AOP是通过实时代理来实现的,这个对象将总是一个代理的对象。
  • AOP proxy:为了实现切面约束而由AOP框架创建的对象就是AOP proxy。在Spring框架中,AOP的代理就是JDK动态代理或者CGLIB代理。
  • Weaving:和应用其他类型连接的切面,或者是创建的Advice对象的过程。这一过程可以在编译期(使用AspectJ编译器),加载期,或者运行时完成。Spring AOP和其它的纯Java的AOP框架一样,是在运行时执行Weaving过程的。

Advice的类型

  • Before Advice: 在JoinPoint执行之前执行的Advice,但是不能够阻止JoinPoint的执行,除非抛出异常。
  • After Returning Advice:在JoinPoint正常完成的情况下执行的Advice,简单来说,就是一个方法没有抛出异常。
  • After Throwing Advice:在JoinPoint不正常完成的情况下执行的Advice,简来单说,就是方法抛出异常的时候执行的Advice。
  • After(finally) Advice:无论一个JoinPoint执行正常还是非正常,都会执行的Advice。
  • Around Advice:以一层调用包裹了JoinPoint的Advice,这是最常见,最有效的一种Advice。Around Adivce可以执行定制的行为,无论是在方法的执行之前还是执行之后。Around Advice也负责决定是否开始进入JoinPoint或者是执行方法其他方法来返回或者抛出异常。

Around Advice也是最泛化的一种Advice。但是Spring AOP中,像AspectJ都提供了很多不同类型的Advice,所以我们仍然建议开发者少使用Around Advice,而是使用最合适的Advice来实现特定的行为。举例来说,如果开发者只需要更新一个缓存来返回方法的值,那么实现一个Returning Advice就比Around Advice更好,尽管Around Advice也能够实现同样的功能。使用更为具体的Advice类型可以简化变成的模型,去除一些潜在的错误。举例来说,开发者在Around Advice上不需要在JoinPoint上调用proceed()方法,一旦调用就可能产生错误。

在Spring 2.0的版本中,所有的参数都是静态的定义的,所以当开发者使用Advice的参数的时候,可以使用适当的类型而不是Object的数组。

JoinPoint的执行和PointCut的匹配概念,是AOP区别于老的的拦截技术的关键。PointCut使得Advice可以独立于面向对象层次来执行。举例来说,一个提供显式的事务管理的Around Advice可以用于多个对象,跨越多个不同的服务层级而工作。

Spring AOP的能力和目的

Spring AOP是纯Java实现的。不需要其他特殊的处理。Spring AOP也不需要控制类加载的层次,所以在应用服务器或者是Servlet容器中应用都很方便。

Spring AOP 当前只支持方法执行的JoinPoint(基于Spring Bean方法的Advice执行),实例变量的拦截是不支持的,尽管支持这个功能也不会破坏掉Spring AOP核心的API。如果开发者需要针对实例变量的访问和更新JoinPoint的话,可以考虑使用AspectJ语言。

Spring AOP框架和其他的AOP框架细节上还是有些不同的。Spring的目的不是为了支持最完整的AOP实现(尽管Spring AOP功能很完善),Spring AOP更多关心的是提供AOP和Spring IoC的集成,以便能够解决企业级应用的常见问题。

比如,Spring框架的AOP功能通常都是结合Spring IoC容器来使用的。切面的配置,也基本都是使用Bean定义的语法(当然Spring AOP也支持强大的自动代理的能力),这就是和其它AOP实现的一个最大的不同。当然,使用Spring AOP也会有一些限制,比如Advice一些细粒度的对象(比如域对象之类的)很难:如果AOP面对的常见问题多数是这种情况的话,使用AspectJ可能是更好的选择。当然,Spring团队的经验是,Spring AOP对绝大多数的企业应用场景,都是十分适用的。

Spring AOP不会努力去实现所有AspectJ的功能以提供完整的AOP解决方案。我们相信无论是基于代理的框架像Spring AOP或者是成熟的AOP框架,比如AspectJ都是十分有价值的,并且他们是相互补充的关系,而并非竞争的关系。Spring通过AspectJ无缝地集成了Spring AOP和IoC,使得所有基于Spring的应用架构能够方便的集成AOP。这种集成不会影响Spring AOP的API或者AOP联盟的API:Spring AOP仍然保持向后兼容。

Spring框架的核心原则之一就是non-invasiveness(轻量级),这一概念的意思就是开发者不必强制引入一些框架的类和接口到应用的业务层或者是模型层。当然,有的时候,Spring框架也支持开发者引入框架的特定依赖:之所以Spring提供这样的支持,是因为在某些场景下,使用Spring框架的特定类能更简单的实现这些功能。Spring框架(几乎)总会提供这样的选择。开发者可以自由选择是否需要使用来最佳的贴合实际的应用场景。

开发者还可以根据自己的场景来使用不同的AOP框架。开发者使用AspectJ或者Spring AOP都是没有问题的,亦或是使用@AspectJ注解的方式,或者是Spring XML配置的方式,都可以。本章更多介绍的是@AspectJ的方式,是因为Spring团队更偏好基于注解的方式。

AOP 代理

Spring AOP默认情况下是使用标准的JDK 动态代理来作为AOP的代理的,它可以使得任何接口被代理。

Spring AOP也可以使用CGLIB代理。这种代理更多的是代理类,而不是接口。CGLIB默认情况下,是当一个业务对象没有实现接口的时候,来代理的。当然,好的编程习惯肯定最好是基于接口的。业务类通常也会实现多个业务接口。当然,强制使用CGLIB作为代理也是可以的。但是在那种情况下,开发者需要声明方法为并非实现接口的方法,或者需要传递一个代理对象到方法作为具体的类型。

理解Spring AOP是基于代理实现的是非常重要的。在后续的文章中可以看到具体的例子。

Spring AOP(一)——基础概念的更多相关文章

  1. 我所理解的Spring AOP的基本概念

    Spring AOP中的概念晦涩难懂,读官方文档更是像读天书,看了非常多样例后,写一些自己理解的一些spring的概念.要理解面向切面编程,要首先理解代理模式和动态代理模式. 如果一个OA系统中的一个 ...

  2. Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)

    1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后, ...

  3. Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)(转)

    1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后, ...

  4. spring AOP的基本概念

    AOP的概念和使用原因 现实中有一些内容并不是面向对象(OOP)可以解决的,比如数据库事务,它对于企业级的Java EE应用而言是十分重要的,又如在电商网站购物需要经过交易系统.财务系统,对于交易系统 ...

  5. Spring AOP(一)--基本概念

    AOP(Aspect Oriented Programing),意为面向切面编程,其实看了很多书本的介绍和说明,我觉得这些解释都太过书面,也可能是翻译的原因,总觉得还是不太懂,也难以理解这种叫法,尤其 ...

  6. Spring学习十三----------Spring AOP的基本概念

    © 版权声明:本文为博主原创文章,转载请注明出处 什么是AOP -面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 -主要的功能是:日志记录.性能统计.安全控制.事务处理. ...

  7. 循序渐进之Spring AOP(2) - 基本概念

    学习AOP前要先了解几个重要术语:Joinpoint.Pointcut.Advice 仍然以改装车比喻,拿到心爱的汽车后想做改装,第一件事是什么?找到要改装的地方.车上可改装的地方很多,但每个人感兴趣 ...

  8. 【spring mvc】基础概念

    1.容器 servlet容器 负责管理servlet生命周期. web容器–tomcat 负责管理和部署web应用,其本身可能具备servlet容器组件:如果没有,一般能将第三方servlet容器作为 ...

  9. 【AOP】Spring AOP基础 + 实践 完整记录

    Spring AOP的基础概念 ============================================================= AOP(Aspect-Oriented Pr ...

  10. [Spring框架]Spring AOP基础入门总结一.

    前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...

随机推荐

  1. February 26 2017 Week 9 Sunday

    There is only one happiness in life, to love and be loved. 生命中只有一种幸福,爱与被爱. Some one told me that hea ...

  2. 统计一段文章的单词频率,取出频率最高的5个单词和个数(python)

    练习题:统计一段英语文章的单词频率,取出频率最高的5个单词和个数(用python实现) 先全部转为小写再判定 lower() 怎么判定单词? 1 不是字母的特殊字符作为分隔符分割字符串 (避免特殊字符 ...

  3. 【转载】#445 - Differences Between an Interface and an Abstract Class

    An interface provides a list of members, without an implementation, that a class can choose to imple ...

  4. 【[HAOI2016]找相同字符】

    其实这道题跟[AHOI2013]差异很像 其实这个问题的本质就是让你算所有后缀的\(lcp\)长度之和,但是得来自两个不同的字符串 先把两个字符串拼起来做一遍\(SA\),由于我们多算了来自于同一个串 ...

  5. Spring data jpa命名规范

    JPA命名规范 (sample与JPQL等效) Table 4. Supported keywords inside method names Keyword Sample JPQL snippet ...

  6. Idea 配置 Database 组件的MySql数据库连接

    1.选择MySql

  7. 原生ajax、XMLHttpRequest和FetchAPI简单描述

    什么是ajax ajax的出现,刚好解决了传统方法的缺陷.AJAX 是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个 ...

  8. 【洛谷P3388】(模板)割点

    [模板]割点 割点集合:一个顶点集合V,删除该集合的所有定点以及与这些顶点相连的边后,原图不连通,就称集合V为割点集合 点连通度:最小割点集合中的顶点数 边连通度:最小割边集合中的边数 割点:割点集合 ...

  9. c#正则表达式最简demo

    各个语言的正则表达式规则略有不同 项目中用到,所以将这个最简单的demo记录 using System; using System.Collections.Generic; using System. ...

  10. 菜鸟笔记 -- Chapter 6.2.2 标识符

    6.2.2  标识符 Java中使用标识符来作为类.方法.字段的名称,在Java基础中我们已经简单了解过标识符的定义方法和驼峰命名.本节我们来研究一下标识符的长度问题,难道类名.方法名都可以无限长吗? ...