面向切面编程(Aspect-oriented Programming,俗称AOP)提供了一种面向对象编程(Object-oriented Programming,俗称OOP)的补充,面向对象编程最核心的单元是类(class),然而面向切面编程最核心的单元是切面(Aspects)。与面向对象的顺序流程不同,AOP采用的是横向切面的方式,注入与主业务流程无关的功能,例如事务管理和日志管理。
Spring的一个关键组件是AOP框架。 虽然Spring IoC容器不依赖于AOP(意味着你不需要在IOC中依赖AOP),但AOP为Spring IoC提供了非常强大的中间件解决方案。
AOP 是一种编程范式,最早由 AOP 联盟的组织提出的,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。它是 OOP的延续。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
我们之间的开发流程都是使用顺序流程,那么使用 AOP 之后,你就可以横向抽取重复代码,什么叫横向抽取呢?或许下面这幅图你能理解,先来看一下传统的软件开发存在什么样风险。
纵向继承体系:
在改进方案之前,我们或许都遇到过 IDEA 对你输出 Duplicate Code 的时候,这个时候的类的设计是很糟糕的,代码写的也很冗余,基本上 if...else... 完成所有事情,这个时候就需要把相同的代码抽取出来成为公共的方法,降低耦合性。这种提取代码的方式是纵向抽取,纵向抽取的代码之间的关联关系非常密切。
横向抽取也是代码提取的一种方式,不过这种方式不会修改主要业务逻辑代码,只是在此基础上添加一些与主要的业务逻辑无关的功能,AOP 采取横向抽取机制,补充了传统纵向继承体系(OOP)无法解决的重复性 代码优化(性能监视、事务管理、安全检查、缓存),将业务逻辑和系统处理的代码(关闭连接、事务管理、操作日志记录)解耦。
在深入学习SpringAOP 之前,让我们先对AOP的几个基本术语有个大致的概念,这些概念不是很容易理解,比较抽象,可以知道有这么几个概念,下面一起来看一下:
切面(Aspect): Aspect 声明类似于 Java 中的类声明,事务管理是AOP一个最典型的应用。在AOP中,切面一般使用 @Aspect 注解来使用,在XML 中,可以使用 <aop:aspect> 来定义一个切面。
连接点(Join Point): 一个在程序执行期间的某一个操作,就像是执行一个方法或者处理一个异常。在Spring AOP中,一个连接点就代表了一个方法的执行。
通知(Advice): 在切面中(类)的某个连接点(方法出)采取的动作,会有四种不同的通知方式: around(环绕通知),before(前置通知),after(后置通知), exception(异常通知),return(返回通知)。许多AOP框架(包括Spring)将建议把通知作为为拦截器,并在连接点周围维护一系列拦截器。
切入点(Pointcut):表示一组连接点,通知与切入点表达式有关,并在切入点匹配的任何连接点处运行(例如执行具有特定名称的方法)。由切入点表达式匹配的连接点的概念是AOP的核心,Spring默认使用AspectJ切入点表达式语言。
介绍(Introduction): introduction可以为原有的对象增加新的属性和方法。例如,你可以使用introduction使bean实现IsModified接口,以简化缓存。
目标对象(Target Object): 由一个或者多个切面代理的对象。也被称为"切面对象"。由于Spring AOP是使用运行时代理实现的,因此该对象始终是代理对象。
AOP代理(AOP proxy): 由AOP框架创建的对象,在Spring框架中,AOP代理对象有两种:JDK动态代理和CGLIB代理
织入(Weaving): 是指把增强应用到目标对象来创建新的代理对象的过程,它(例如 AspectJ 编译器)可以在编译时期,加载时期或者运行时期完成。与其他纯Java AOP框架一样,Spring AOP在运行时进行织入。
Spring AOP 中通知的分类前置通知(Before Advice): 在目标方法被调用前调用通知功能;相关的类org.springframework.aop.MethodBeforeAdvice
后置通知(After Advice): 在目标方法被调用之后调用通知功能;相关的类org.springframework.aop.AfterReturningAdvice
返回通知(After-returning): 在目标方法成功执行之后调用通知功能;
异常通知(After-throwing): 在目标方法抛出异常之后调用通知功能;相关的类org.springframework.aop.ThrowsAdvice