Spring学习笔记:AOP

AOP:Aspect Oriented Programming 面向切面编程

主要参考资料:维基百科-AOP

WHY

设想这样一个应用场景:设计一个计算器,要求在每次程序执行运算前后输出日志,追踪正在发生的活动

一般方法:在程序执行前和执行后分别重复添加System.out.println();语句,汇报执行进度

带来的两个主要问题:一是代码分散,为了满足某个单一需求,需要在各个模块重复添加相同的语句,一旦需要改动,则全部语句需要逐一改动,很麻烦;二是代码混乱,核心业务代码之外混杂了这些日志代码等非业务需求代码,每个模块需要兼顾多个点,维护困难

AOP的好处:每个业务逻辑位于一个位置,代码不分散,便于维护和升级,业务模块更简洁,只包含核心业务代码

业务逻辑:验证参数—前置日志—核心方法—后置日志

把每一个部分单独拿出来就叫抽取横切关注点


WHAT

AOP是一种程序设计思想,旨在将横切关注点与业务主体进一步分离,以提高程序代码的模块化程度。通过在现有代码基础上增加额外的通知(Advice)机制,能够对被声明为“切点(Pointcut)”的代码块进行统一管理与装饰,如“对所有方法名以‘set*’开头的方法添加后台日志”。该思想使得开发人员能够将与代码核心业务逻辑关系不那么密切的功能(如日志功能)添加至程序中,同时又不降低业务代码的可读性。面向切面编程将代码逻辑切分为不同的模块(即关注点(Concern),一段特定的逻辑功能)。几乎所有的编程思想都涉及代码功能的分类,将各个关注点封装成独立的抽象模块(如函数、过程、模块、类以及方法等),后者又可供进一步实现、封装和重写。部分关注点“横切”程序代码中的数个模块,即在多个模块中都有出现,它们即被称作“横切关注点(Cross-cutting concerns, Horizontal concerns)”。

在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。这样看来,AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。有了AOP,OOP变得立体了。如果加上时间维度,AOP使OOP由原来的二维变为三维了,由平面变成立体了。从技术上来说,AOP基本上是通过代理机制实现的。对OOP编程是一种十分有益的补充。

日志功能即是横切关注点的一个典型案例,因为日志功能往往横跨系统中的每个业务模块,即“横切”所有有日志需求的类及方法体。而对于一个信用卡应用程序来说,存款、取款、帐单管理是它的核心关注点,日志和持久化将成为横切整个对象结构的横切关注点。切面的概念源于对面向对象的程序设计的改进,但并不只限于此,它还可以用来改进传统的函数。与切面相关的编程概念还包括元对象协议、主题(Subject)、混入(Mixin)和委托(Delegate)。

AOP的相关术语:

  • 关注点(concern):对软件工程有意义的小的、可管理的、可描述的软件组成部分
  • 主关注点(core concern):一个软件最主要的关注点
  • 关注点分离(separation of concerns,SOC):标识、封装和操纵只与特定概念、目标相关的软件组成部分的能力,即标识、封装和操纵关注点的能力
  • 横切(crosscut):两个关注点,如果实现他们的方法(method)存在交集,则相互横切
  • 支配性分解(dominant decomposition):将软件分解成模块的主要方式,传统的程序设计语言是以一种线性的文本来描述软件,只采用一种方式(比如类)将软件分解成模块;这导致某些关注点比较好被捕捉,容易进一步组合扩展;但还有一些关注点没有被捕捉,弥散在整个软件内部。支配性分解一般是按主关注点进行模块分解的
  • 横切关注点(crosscutting concerns):除了主关注点能被支配性分解捕捉以外,还有很多没有被捕捉到的关注点,弥散在整个软件内部,这些关注点同主关注点是横切的
  • 切面(aspect):在支配性分解的基础上,提供的一种辅助的模块化机制,可以捕捉横切关注点
  • 通知(advice):切面必须要完成的工作
  • 目标(target):被通知的对象
  • 代理(proxy):向目标对象应用通知之后创建的对象
  • 连接点(joinpoint):程序执行的某个特定位置

HOW