《Spring技术内幕》——3.1节Spring AOP概述

第3章
Spring AOP的实现
好雨知时节,当春乃发生。
随风潜入夜,润物细无声。
野径云俱黑,江船火独明。
晓看红湿处,花重锦官城。
—【唐】杜甫《春夜喜雨》
本章内容

  • Spring AOP概述
  • Spring AOP的设计与实现
  • 建立AopProxy代理对象
  • Spring AOP拦截器调用的实现
  • Spring AOP的高级特性
    3.1 Spring AOP概述

AOP是Aspect-Oriented Programming(面向方面编程或面向切面)的简称,维基百科对它的解释如下。
维基百科对“AOP”相关概念的叙述
Aspect是一种新的模块化机制,用来描述分散在对象、类或函数中的横切关注点(crosscutting concern)。从关注点中分离出横切关注点是面向切面的程序设计的核心概念。分离关注点使解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通过切面来封装、维护,这样原本分散在整个应用程序中的变动就可以很好地管理起来。
这里提到的概念是从模块化出发的,开发者一定不会对模块化这个概念感到陌生。记得我初学编程(C语言)时,总喜欢把所有代码写进一个main函数里。这种编码方式造成了一个很不好的后果—程序的维护性很差。如果程序规模较小,而且是由一个人开发完成的,维护时还能控制;如果程序规模较大,而且需要多个人合作才能完成,维护时就会遇到很大的麻烦。再加上当时根本没有版本管理的概念,随着项目进展,功能越加越多,整个程序就逐渐变成了一团乱麻。
经过一段痛苦的经历后,我终于在开发实践中对软件工程的相关概念有了一些认识,开始明白了自己原来只是在写程序,并不是在开发软件,更谈不上是在开发软件产品了。痛定思痛,我不断地在编码中学习和思考,开始使用子函数来对程序进行模块划分,并对一些基本的功能进行封装。当时只是希望一个函数不要太长,能把不同的功能模块分给不同的开发人员完成。想法虽简单,但每个开发人员都渴望这样做,就像普通开发人员对优秀的架构师的渴望一样。有了架构师,每个人就可以各自负责自己的“一亩三分地”,日子也许就好过了!
但是很不幸,万能的架构师始终没有出现,最后只能自己想办法:在工作中总结,在教训中学习,在摸索中前进。在成长的过程中,很自然地发现,将一些代码用子函数封装以后,只要把接口定义设计好,子函数中的代码变动是不会对主程序中的代码产生太大影响的,从而大大降低了维护的成本。
后来,为了让代码的维护更方便,又把不同的子函数的实现放到了不同的文件中。这样更方便了,不仅不用在一长串的代码文件里查找和维护,还可以让不同的开发人员并行开发和维护,大大提高了开发效率。除了技术方面的提高,还有精神上的收获。这种分而治之的策略让我慢慢具备了设计大型程序的信心,不会再为那些长长的代码感到头疼。用这种方法来编写一般的C语言程序基本没问题,直到后来涉及面向对象的程序设计,新的问题又出现了。
有了一定的面向对象编程经验后发现,面向对象设计其实也是一种模块化的方法,它把相关的数据及其处理方法放在了一起。与单纯使用子函数进行封装相比,面向对象的模块化特性更完备,它体现了计算的一个基本原则—让计算尽可能靠近数据。这样一来,代码组织起来就更加整齐和清晰,一个类就是一个基本的模块。很多程序的功能还可以通过设计类的继承关系而得到重用,进一步提高了开发效率。再后来,又出现了各种各样的设计模式,使设计程序功能变得更加得心应手。
后来又在开发中发现了一些问题。虽然利用面向对象的方法可以很好地组织代码,也可以通过继承关系实现代码重用,但是程序中总是会出现一些重复的代码,而且不太方便使用继承的方法把它们重用和管理起来。它们功能重复并且需要用在不同的地方,虽然可以对这些代码做一些简单的封装,使之成为公共函数,但是在这种显式的调用中,使用它们并不是很方便。例如,这个公共函数在什么情况下可以使用,能不能更灵活地使用等。
另外,在使用这些公共函数的时候,往往也需要进行一些逻辑设计,也就是需要代码实现来支持,而这些逻辑代码也是需要维护的。这时就是AOP大显身手的时候,使用AOP后,不仅可以将这些重复的代码抽取出来单独维护,在需要使用时统一调用,还可以为如何使用这些公共代码提供丰富灵活的手段。这虽然与设计公共子模块有几分相似,但在传统的公共子模块调用中,除了直接硬调用之外并没有其他的手段,而AOP为处理这一类问题提供了一套完整的理论和灵活多样的实现方法。也就是说,通过AOP提出横切的概念以后,在把模块功能正交化的同时,也在此基础上提供了一系列横切的灵活实现。比如通过使用Proxy代理对象、拦截器字节码翻译技术等一系列已有的AOP或者AOP实现技术,来实现切面应用的各种编织实现和环绕增强;为了更好地应用AOP技术,技术专家们还成立了AOP联盟来探讨AOP的标准化,有了这些支持,AOP的发展就更快了。关于AOP技术,可以到AOP联盟的文档里找到一些相关的介绍,从而加强对AOP的理解。比如,在AOP联盟的网站上有以下AOP技术:

  • AspectJ:源代码和字节码级别的编织器,用户需要使用不同于Java的新语言。
  • AspectWerkz:AOP框架,使用字节码动态编织器和XML配置。
  • JBoss-AOP:基于拦截器和元数据的AOP框架,运行在JBoss应用服务器上。以及在AOP中用到的一些相关的技术实现:
  • BCEL(Byte-Code Engineering Library):Java字节码操作类库,具体的信息可以参见项目网站http://jakarta.apache.org/bcel/
  • Javassist:Java字节码操作类库,JBoss的一个子项目,项目信息可以参见项目网站http://jboss.org/javassist/
    对应于现有的AOP实现方案,AOP联盟对它们进行了一定程度的抽象,从而定义出AOP体系结构。结合这个AOP体系结构去了解AOP技术,对我们理解AOP的概念是非常有帮助的,AOP联盟定义的AOP体系结构如图3-1所示。

AOP联盟定义的AOP体系结构把与AOP相关的概念大致分为由高到低、从使用到实现的三个层次。从上往下,最高层是语言和开发环境,在这个环境中可以看到几个重要的概念:“基础”(base)可以视为待增强对象或者说目标对象;“切面”(aspect)通常包含对于基础的增强应用;“配置”(configuration)可以看成是一种编织,通过在AOP体系中提供这个配置环境,可以把基础和切面结合起来,从而完成切面对目标对象的编织实现。
在Spring AOP实现中,使用Java语言来实现增强对象与切面增强应用,并为这两者的结合提供了配置环境。对于编织配置,毫无疑问,可以使用IoC容器来完成;对于POJO对象的配置,本来就是Spring的核心IoC容器的强项。因此,对于使用Spring的AOP开发而言,使用POJO就能完成AOP任务。但是,对于其他的AOP实现方案,可能需要使用特定的实现语言、配置环境甚至是特定的编译环境。例如在AspectJ中,尽管切面增强的对象是Java对象,但却需要使用特定的Aspect语言和AspectJ编译器。AOP体系结构的第二个层次是为语言和开发环境提供支持的,在这个层次中可以看到AOP框架的高层实现,主要包括配置和编织实现两部分内容。例如配置逻辑和编织逻辑实现本身,以及对这些实现进行抽象的一些高层API封装。这些实现和API封装,为前面提到的语言和开发环境的实现提供了有力的支持。
最底层是编织的具体实现模块,图3-1中的各种技术都可以作为编织逻辑的具体实现方法,比如反射、程序预处理、拦截器框架、类装载器框架、元数据处理等。阅读完本章对Spring AOP实现原理的分析,我们可以了解到,在Spring AOP中,使用的是Java本身的语言特性,如Java Proxy代理类、拦截器等技术,来完成AOP编织的实现。

对Spring平台或者说生态系统来说,AOP是Spring框架的核心功能模块之一。AOP与IoC容器的结合使用, 为应用开发或Spring自身功能的扩展都提供了许多便利。Spring AOP的实现和其他特性的实现一样,除了可以使用Spring本身提供的AOP实现之外,还封装了业界优秀的AOP解决方案AspectJ来供应用使用。本章主要对Spring自身的AOP实现原理进行分析。在这个AOP实现中,Spring充分利用了IoC容器Proxy代理对象以及AOP拦截器的功能特性,通过这些对AOP基本功能的封装机制,为用户提供了AOP的实现框架。因此,要了解这些AOP的基本实现,需要对Java 的Proxy机制有一些基本了解。在Spring中,有一些相关的概念与AOP设计相对应。本章将按照笔者个人的理解,结合Spring的AOP实现,先简单地回顾一些相关的AOP概念,然后逐步展开对AOP实现原理的分析,通过对实现原理的分析来了解Spring AOP模块,在这些实现原理的分析中,包括代理对象的生成、AOP拦截器的实现等。在分析中,以ProxyFactoryBean和ProxyFactory为例进行说明。

时间: 2024-09-13 04:04:50

《Spring技术内幕》——3.1节Spring AOP概述的相关文章

《Spring技术内幕》——1.1节Spring的各个子项目

第1章 Spring的设计理念和整体架构 横看成岭侧成峰,远近高低各不同. 不识庐山真面目,只缘身在此山中. -[宋]苏轼<题西林壁> 本章内容 Spring的各个子项目 Spring的设计目标 Spring的整体架构 Spring的应用场景 1.1 Spring的各个子项目 打开Spring社区网站http://www.springsource.org, 我们可以看到围绕Spring核心构建出的一个丰富的平台生态系统.在这个平台生态系统中,除了Spring本身,还有许多值得注意的子项目.对S

《Spring技术内幕》——1.4节Spring的应用场景

1.4 Spring的应用场景 通过介绍Spring架构设计,我们了解到Spring是一个轻量级的框架.在Spring这个一站式的应用平台或框架中,其中的各个模块除了依赖IoC容器和AOP之外,相互之间并没有很强的耦合性.Spring的最终目标是简化应用开发的编程模型.它所提供的服务,可以贯穿应用到整个软件中,从最上层的Web UI到底层的数据操作,到其他企业信息数据的集成,再到各种J2EE服务的使用,等等.这些企业应用服务,Spring都通过其特有的IoC容器和AOP模块实现.在实现过程中,S

《Spring技术内幕》——1.2节Spring的设计目标

1.2 Spring的设计目标 如果我们要简要地描述Spring的设计目标,可以这么说,Spring为开发者提供的是一个一站式的轻量级应用开发框架(平台).作为平台,Spring抽象了我们在许多应用开发中遇到的共性问题:同时,作为一个轻量级的应用开发框架,Spring和传统的J2EE开发相比,有其自身的特点.通过这些自身的特点, Spring充分体现了它的设计理念:在Java EE的应用开发中,支持POJO和使用JavaBean的开发方式,使应用面向接口开发,充分支持OO(面向对象)的设计方法.

《Spring技术内幕》——1.3节Spring的整体架构

1.3 Spring的整体架构 了解了Spring的设计理念之后,我们继续介绍Spring的整体架构.在Spring中,我们大致按照一个参考关系,将其划分为几个层次,比如IoC容器.AOP核心模块.封装的Java EE服务.作为中间的驱动组件.其他作为上层的应用,这些应用不但包括来源于社区的应用封装,如ACEGI,也包括使用Spring作为平台开发出来的各种类型的企业应用. 从技术上看,Spring是封装得很清晰的一个分层架构,可以参考如图1-4所示的Spring架构图. 在这个架构图中,我们可

《Spring技术内幕》——1.5节小结

1.5 小结 本章简要回顾了Spring的设计理念.架构设计和应用场景.在Spring的整体架构中,我们对Spring的各个模块和模块关系进行了简要的介绍,在后面的章节中,我们还会对这些模块的实现细节和设计进行更为详细的阐述.在Spring的应用场景中,众所周知的SSH是我们常见的技术选择,但不见得Spring就只能在这个组合中出现,因为Spring自身也包括了MVC框架.数据持久化操作等,同时也因为Spring自身设计的模块化很好,所以,在使用Spring的时候,对Spring可以按不同角度进

《Spring技术内幕》——2.2节IoC容器系列的设计与实现:BeanFactory和ApplicationContext

2.2 IoC容器系列的设计与实现:BeanFactory和ApplicationContext在Spring IoC容器的设计中,我们可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能:另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在.应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境作了许多适配.有了这两种基本的容器系列,基本上可以满足用户对IoC容器使用的大部分需求了.下面

《Spring技术内幕》——2.3节IoC容器的初始化过程

2.3 IoC容器的初始化过程 简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动.具体来说,这个启动包括BeanDefinition的Resouce定位.载入和注册三个基本过程.如果我们了解如何编程式地使用IoC容器,就可以清楚地看到Resource定位和载入过程的接口调用.在下面的内容里,我们将会详细分析这三个过程的实现. 在分析之前,要提醒读者注意的是,Spring把这三个过程分开,并使用不同的模块来完成,如使用相应的Resourc

《Spring技术内幕》——第一部分

第一部分 Spring核心实现篇 第2章 Spring Framework的核心:IoC容器的实现 第3章 Spring AOP的实现 本篇将对Spring的核心IoC容器和AOP的实现原理进行阐述.IoC容器和AOP是Spring的核心,它们是Spring系统中其他组件模块和应用开发的基础.通过这两个核心模块的设计和实现可以了解Spring倡导的对企业应用开发所应秉持的思路,比如使用POJO开发企业应用,提供一致的编程模型,强调对接口编程等.对于这些Spring背后的开发思想和设计理念,大家都

《Spring技术内幕》——导读

目 录 前言 第1章 Spring的设计理念和整体架构1.1 Spring的各个子项目 1.2 Spring的设计目标 1.3 Spring的整体架构 1.4 Spring的应用场景 1.5 小结 第一部分 Spring核心实现篇 第2章 Spring Framework的核心:IoC容器的实现 2.1 Spring IoC容器概述2.2 IoC容器系列的设计与实现:BeanFactory和ApplicationContext 2.3 IC容器的初始化过程 2.4 IoC容器的依赖注入 2.5