Loading

Spring AOP 用法浅谈(Day_18)

 

 当你这一天没有在进步,那你就是在退步!

 


 

【简述】

  Aspect Oriented Programming :面向切面编程

所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情况下给程序动态添加功能的技术,取代了传统纵向继承体系的重复性代码

AOP把软件的功能模块分为两个部分:核心关注点横切关注点。业务处理的主要功能为核心关注点,而非核心、需要拓展的功能为横切关注点。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点进行分离。

 

 

【概念】

  

  • 增强(Adivce):又翻译成通知,定义了切面是什么以及何时使用,描述了切面要完成的工作和何时需要执行这个工作。是织入到目标类连接点上的一段程序代码。增强包含了用于添加到目标连接点上的一段执行逻辑,又包含了用于定位连接点的方位信息。(所以spring提供的增强接口都是带方位名:BeforeAdvice、(表示方法调用前的位置)AfterReturninAdvice、(表示访问返回后的位置)ThrowAdvice等等,所以只有结合切点和增强两者一起才能确定特定的连接点并实施增强逻辑)

 

  • 切入点(Pointcut):Advice定义了切面要发生“故事”和时间,那么切入点就定义了“故事”发生的地点。例如某个类或者方法名,Spring中允许我们使用正则来指定。

 

  • 连接点(Joinpoint):切入点匹配的执行点称作连接点。如果说切入点是查询条件,那连接点就是被选中的具体的查询结果。程序执行的某个特定位置,程序能够应用增强代码的一个“时机”,比如方法调用或者特定异常抛出

 

  • 切面(Aspect):切点和增强组成切面。它包括了横切逻辑的定义,也包括了连接点的定义。Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中

 

  • 代理(Proxy):AOP框架创建的对象。一个类被AOP织入增强之后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。

 

  • 目标对象(Target):增强逻辑的织入的目标类

 

  • 织入(Weaving):将增强添加到目标类具体连接点上的过程。AOP有三种织入的方式:编译期织入、类装载期织入、动态代理织入(spring采用动态代理织入)

  

通知(Advice)类型:

  • 前置通知(Before advice):在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。例如,TestAspect中的doBefore方法。

 

  • 后置通知(After advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。例如,ServiceAspect中的returnAfter方法,所以Teser中调用UserService.delete抛出异常时,returnAfter方法仍然执行。

 

  • 返回后通知(After return advice):在某连接点正常完成后执行的通知,不包括抛出异常的情况。ApplicationContext中在<aop:aspect>里面使用<after-returning>元素进行声明。

 

  • 环绕通知(Around advice):包围一个连接点的通知,类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。例如,ServiceAspect中的around方法。

 

  • 抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。例如,ServiceAspect中的returnThrow方法。

注:可以将多个通知应用到一个目标对象上,即可以将多个切面织入到同一目标对象。

 

  结构图:

 

 

 

 

 

 

 

 

 

【实现】

  关于AOP有两种实现方式,一是基于注解的方式,二是xml配置方式。

使用之前,我们先了解下execution表达式,execution表达式是我们在开发过程中最常用的,它的语法如下:

 1 execution {
 2 
 3     modifier-pattern?
 4 
 5     ret-type-pattern?
 6 
 7     declaring-type-pattern?
 8 
 9     name-pattern(param-pattern)
10 
11     throws-pattern?
12 
13 }

 

 

 

modifier-pattern:用于匹配public、private等访问修饰符

  ret-type-pattern:用于匹配返回值类型,不可省略

  declaring-type-pattern:用于匹配包类型

  modifier-pattern(param-pattern):用于匹配类中的方法,不可省略

  throws-pattern:用于匹配抛出异常的方法

 

 

 

下面我会基于两种举例实现。

 

一、@Annotation

 

 待续。。。。。。

 

 

posted @ 2020-11-22 13:16  A零号  阅读(113)  评论(0编辑  收藏  举报