SpringAop知识点理解


前言

springaop是spring中的重要组成,本人对springaop的知识点做了一些简单的归纳,希望对于学习与理解springaop有一定帮助。

什么是Spring Aop

Spring AOP(Aspect Oriented Programming,面向切面编程)是OOPs(面向对象编程)的补充,它也提供了模块化。在面向对象编程中,关键的单元是对象,AOP的关键单元是切面,或者说关注点(可以简单地理解为你程序中的独立模块)。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。一个横切关注点是一个可以影响到整个应用的关注点,而且应该被尽量地集中到代码的一个地方,例如事务管理、权限、日志、安全等。
AOP让你可以使用简单可插拔的配置,在实际逻辑执行之前、之后或周围动态添加横切关注点。这让代码在当下和将来都变得易于维护。如果你是使用XML来使用切面的话,要添加或删除关注点,你不用重新编译完整的源代码,而仅仅需要修改配置文件就可以了。
Spring AOP通过以下两种方式来使用。但是最广泛使用的方式是Spring AspectJ 注解风格(Spring AspectJ Annotation Style)

  • 使用AspectJ 注解风格
  • 使用Spring XML 配置风格

SpringAop中关注点与横切关注点

关注点是我们想在应用的模块中实现的行为。关注点可以被定义为:我们想实现以解决特定业务问题的方法。比如,在所有电子商务应用中,不同的关注点(或者模块)可能是库存管理、航运管理、用户管理等。
横切关注点是贯穿整个应用程序的关注点。像日志、安全和数据转换,它们在应用的每一个模块都是必须的,所以他们是一种横切关注点。

什么是Aspect?

AspectPointCutAdvice组成

它即包含了横切逻辑的定义,也包括了连接点的定义

SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑编辑到切面指定的连接点中

AOP的工作重心在于如何将增强编织目标对象的连接点中,这里包含两个工作:

1.如何通过PointCut和Advice定位到特定的JoinPoint上

2.如何Advice中编写切面编程
其实可以简单地认为,使用@aspect注解的类就是一个切面类

什么是JoinPoint?

JoinPoint,切点,程序运行中的一些时间点,例如:

一个方法的执行

或者是一个异常处理

在SpringAOP中,JoinPoint总是方法的执行点

什么是PointCut?

PointCut,匹配JOinPoint的谓词(a predicate that matches join points)

简单来说,PointCut是匹配JoinPoint的条件

Advice是和特定PointCut关联的,并且在PointCut相匹配的JoinPoint中执行,即Advice=>PointCut=>JoinPoint.

在Spring中,所有的方法都可以认为JoinPoint,但是我们并不希望在所有方法上都添加Advice。而PointCut的作用,就是提供一组规则(使用 AspectJ PointCut expression language来描述)来匹配JoinPoint,给满足规则的JoinPoint添加Advice

连接点(Joint Point)和切入点(Point cut)的联系?

连接点是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。举例来说,所有定义在你的 EmpoyeeManager 接口中的方法都可以被认为是一个连接点,如果你在这些方法上使用横切关注点的话。
切入点(切入点)是一个匹配连接点的断言或者表达式。Advice 与切入点表达式相关联,并在切入点匹配的任何连接点处运行(比如,表达式 execution(* EmployeeManager.getEmployeeById(...)) 可以匹配 EmployeeManager 接口的 getEmployeeById() )。由切入点表达式匹配的连接点的概念是 AOP 的核心。Spring 默认使用 AspectJ 切入点表达式语言。

什么是Advice?

Advice,通知

特定JoinPoint处的Aspect所采取的动作称为Advice。

SpringAop使用一个Advice作为拦截器,在JoinPoint周围维护一系列的拦截器

Spring中有哪些不同的Advice类型

通知(advice)是你在你的程序中想要应用在其他模块中的横切关注点的实现。Advice主要有以下5种类型:

  1. 前置通知(Before Advice): 在连接点之前执行的Advice,不过除非它抛出异常,否则没有能力中断执行流。使用 @Before 注解使用这个Advice。
  2. 返回之后通知(After Retuning Advice): 在连接点正常结束之后执行的Advice。例如,如果一个方法没有抛出异常正常返回。通过 @AfterReturning 关注使用它。
  3. 抛出(异常)后执行通知(After Throwing Advice): 如果一个方法通过抛出异常来退出的话,这个Advice就会被执行。通用 @AfterThrowing 注解来使用。
  4. 后置通知(After Advice): 无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会执行在结束后执行这些Advice。通过 @After 注解使用。
  5. 围绕通知(Around Advice): 围绕连接点执行的Advice,就你一个方法调用。这是最强大的Advice。通过 @Around 注解使用。

什么是 Target ?

Target,织入Advice的目标对象。目标对象也被称为 Advised Object

因为SpringAOP使用运行时代理的方式来实现Aspect因此AdvisedObject总是一个代理对象(Proxied Object)

注意Advised Object指的不是原来的对象,而是织入Advice后所产生的代理对象

advice+Target Object = Advised Object = Proxy。

AOP的实现方式

实现AOP的技术,主要分为两类:

静态代理指使用AOP框架停工的命令进行编译,从而在编译阶段就可以生成AOP代理类,因此也称为AOP代理类,因此也称为编译时增强

编译时编织(特殊编译器实现)

类加载时编织(特殊的类加载器实现)

动态代理在运行时在内存中临时生成AOP动态代理类,因此也被称为运行时增强,目前Spring中使用了两种代理库

JDK动态代理

CGLIB

那么Spring什么时候使用JDK动态代理,什么时候使用CGLIB呢?

  1. Spring AOP部分使用JDK动态代理或则CGLIb来为目标对象创建代理(建议尽量使用JDK的动态代理)
  2. 如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都被该代理
  3. 若该目标对象没有实现任何接口,则创建一个CGLIB代理

SpringAOP中的动态代理主要两种方式

JDK动态代理

JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个借口,JDK动态代理的核心是InvocationHandler接口和Proxy

CGLIB动态代理

如果目标没有实现接口,那么SpringAOP会选择使用CGLIB来动态代理目标类,当然Spring也支持配置强制使用CGLIB动态代理,而CGLIB动态代理的核心是MethodInterceptor接口和enhancer

CGLIB是一个代码生成的类库,可以再运行时动态的生成某个类的子类,注意,CGLIB是通过集成的方式做的动态代理,因此如果某个类被标记为final,那么它无法使用CGLIB做动态代理
如果业务对象没有实现任何接口那么默认使用CGLIB

什么是编织(Weaving)?

为了创建一个Advice对象而链接一个Aspect和其他应用类型或对象,称为编织(Weaving)
在SpringAOP中,编织在运行时执行,即动态代理Weaving

在Spring中可以使用基于XML方式切面实现 或者注解方式实现(个人还是喜欢注解方式)


文章作者: jackey
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 jackey !
评论
  目录