Spring框架——AOP(⾯向切⾯编程)详解
1 AOP概述
●AOP(Aspect-Oriented Programming,⾯向切⾯编程):是⼀种新的⽅法论,是对传统 OOP(Object-Oriented Programming,⾯向对象编程)的补充。
●AOP编程操作的主要对象是切⾯(aspect),⽽切⾯模块化横切关注点。
●在应⽤AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应⽤在哪⾥,以什么⽅式应⽤,并且不必修改受影响的类。这样⼀来横切关注点就被模块化到特殊的类⾥——这样的类我们通常称之为“切⾯”。
●AOP的好处:
○每个事物逻辑位于⼀个位置,代码不分散,便于维护和升级
○业务模块更简洁,只包含核⼼业务代码
2 AOP术语
2.1 横切关注点
  从每个⽅法中抽取出来的同⼀类⾮核⼼业务。(抽离到⽅法中处理⾮核⼼业务)
2.2 切⾯(Aspect)
  封装横切关注点信息的类,每个关注点体现为⼀个通知⽅法。
2.3 通知(Advice)
  切⾯必须要完成的各个具体⼯作
2.4 ⽬标(Target)
  被通知的对象
2.5 代理(Proxy)
  向⽬标对象应⽤通知之后创建的代理对象
2.6 连接点(Joinpoint)
  横切关注点在程序代码中的具体体现,对应程序执⾏的某个特定位置。例如:类某个⽅法调⽤前、调⽤后、⽅法捕获到异常后等。
  在应⽤程序中可以使⽤横纵两个坐标来定位⼀个具体的连接点:
2.7 切⼊点(pointcut):
  定位连接点的⽅式。每个类的⽅法中都包含多个连接点,所以连接点是类中客观存在的事物。如果把连接点看作数据库中的记录,那么切⼊点就是查询条件——AOP可以通过切⼊点定位到特定的连接点。
  切点通过org.springframework.aop.Pointcut 接⼝进⾏描述,它使⽤类和⽅法作为连接点的查询条件。
3 AspectJ
3.1 简介
AspectJ:Java社区⾥最完整最流⾏的AOP框架。
在Spring2.0以上版本中,可以使⽤基于AspectJ注解或基于XML配置的AOP。
3.2 在Spring中启⽤AspectJ注解⽀持
①导⼊JAR包
●aopalliance.jar
●aspectj.weaver.jar
●spring-aspects.jar
②引⼊aop名称空间
③配置
<aop:aspectj-autoproxy>
当Spring IOC容器侦测到bean配置⽂件中的<aop:aspectj-autoproxy>元素时,会⾃动为与AspectJ切⾯匹配的bean创建代理
3.3 ⽤AspectJ注解声明切⾯
①要在Spring中声明AspectJ切⾯,只需要在IOC容器中将切⾯声明为bean实例。②当在Spring IOC容器中初始化AspectJ切⾯之后,Spring IOC容器就会为那些与 AspectJ切⾯相匹配的bean创建代理。
③在AspectJ注解中,切⾯只是⼀个带有@Aspect注解的Java类,它往往要包含很多通知。
④通知是标注有某种注解的简单的Java⽅法。
⑤AspectJ⽀持5种类型的通知注解:
  [1]@Before:前置通知,在⽅法执⾏之前执⾏
  [2]@After:后置通知,在⽅法执⾏之后执⾏
  [3]@AfterRunning:返回通知,在⽅法返回结果之后执⾏
  [4]@AfterThrowing:异常通知,在⽅法抛出异常之后执⾏
  [5]@Around:环绕通知,围绕着⽅法执⾏
4 切⼊点表达式
4.1 作⽤
通过表达式的⽅式定位⼀个或多个具体的连接点。
4.2 语法细节
①切⼊点表达式的语法格式
execution([权限修饰符] [返回值类型] [简单类名/全类名] [⽅法名]([参数列
表]))
②举例说明
表达式execution(* com.atguigu.spring.ArithmeticCalculator.*
(..))
含义ArithmeticCalculator接⼝中声明的所有⽅法。
第⼀个“*”代表任意修饰符及任意返回值。
第⼆个“*”代表任意⽅法。
“..”匹配任意数量、任意类型的参数。
若⽬标类、接⼝与该切⾯类在同⼀个包中可以省略包
名。
表达式execution(public *
ArithmeticCalculator.*(..))
含义ArithmeticCalculator接⼝的所有公有⽅
spring ioc注解
表达式execution(public double ArithmeticCalculator.*(..))
含义ArithmeticCalculator接⼝中返回double类型数值的
⽅法
表达式execution(public double ArithmeticCalculator.*
(double, ..))
含义第⼀个参数为double类型的⽅法。
“..” 匹配任意数量、任意类型的参数。
表达式execution(public double ArithmeticCalculator.*(double,
double))
含义参数类型为double,double类型的⽅法
③在AspectJ中,切⼊点表达式可以通过 “&&”、“||”、“!”等操作符结合起来。
表达式execution (* *.add(int,..)) || execution(* *.sub(int,..))
含义任意类中第⼀个参数为int类型的add⽅法或sub⽅法
含义任意类中第⼀个参数为int类型的add⽅法或sub⽅法
4.3 切⼊点表达式应⽤到实际的切⾯类中
5 当前连接点细节
5.1 概述
切⼊点表达式通常都会是从宏观上定位⼀组⽅法,和具体某个通知的注解结合起来就能够确定对应的连接点。那么就⼀个具体的连接点⽽⾔,我们可能会关⼼这个连接点的⼀些具体信息,例如:当前连接点所在⽅法的⽅法名、当前传⼊的参数值等等。这些信息都封装
在JoinPoint接⼝的实例对象中。
5.2 JoinPoint
6 通知
6.1 概述
l 在具体的连接点上要执⾏的操作。
l ⼀个切⾯可以包括⼀个或者多个通知。
l 通知所使⽤的注解的值往往是切⼊点表达式。
6.2 前置通知
l 前置通知:在⽅法执⾏之前执⾏的通知
l 使⽤@Before注解
6.3 后置通知
l 后置通知:后置通知是在连接点完成之后执⾏的,即连接点返回结果或者抛出异常的时候
l 使⽤@After注解
6.4 返回通知
l 返回通知:⽆论连接点是正常返回还是抛出异常,后置通知都会执⾏。如果只想在连接点返回的时候记录⽇志,应使⽤返回通知代替后置通知。
l 使⽤@AfterReturning注解
l 在返回通知中访问连接点的返回值
在返回通知中,只要将returning属性添加到@AfterReturning注解中,就可以访问连接点的返回值。该属性的值即为⽤来传⼊返回值的参数名称
必须在通知⽅法的签名中添加⼀个同名参数。在运⾏时Spring AOP会通过这个参数传递返回值
原始的切点表达式需要出现在pointcut属性中
6.5 异常通知
l 异常通知:只在连接点抛出异常时才执⾏异常通知
l 将throwing属性添加到@AfterThrowing注解中,也可以访问连接点抛出的异常。Throwable是所有错误和异常类的顶级⽗类,所以在异常通知⽅法可以捕获到任何错误和异常。
l 如果只对某种特殊的异常类型感兴趣,可以将参数声明为其他异常的参数类型。然后通知就只在抛出这个类型及其⼦类的异常时才被执⾏
6.6 环绕通知
l 环绕通知是所有通知类型中功能最为强⼤的,能够全⾯地控制连接点,甚⾄可以控制是否执⾏连接点。
l 对于环绕通知来说,连接点的参数类型必须是ProceedingJoinPoint。它是 JoinPoint的⼦接⼝,允许控制何时执⾏,是否执⾏连接点。
l 在环绕通知中需要明确调⽤ProceedingJoinPoint的proceed()⽅法来执⾏被代理的⽅法。如果忘记这样做就会导致通知被执⾏了,但⽬标⽅法没有被执⾏。
l 注意:环绕通知的⽅法需要返回⽬标⽅法执⾏之后的结果,即调⽤ joinPoint.proceed();的返回值,否则会出现空指针异常。
6.7 重⽤切⼊点定义
l 在编写AspectJ切⾯时,可以直接在通知注解中书写切⼊点表达式。但同⼀个切点表达式可能会在多个通知中重复出现。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。