Files
rikako-note/spring/Spring core/Spring Core AOP.md
2022-07-14 22:58:45 +08:00

4.6 KiB
Raw Blame History

Spring AOP

  • Spring AOP的核心概念

    • Aspect切面一个模块化的考虑
    • Joint Point连接点程序执行时的一个时间点通常是方法的执行
    • Advice当切面在一个切入点执行多做时执行的动作被称之为AdviceAdvice有不同的类型before、after、around
    • Pointcut切入点advice通常运行在满足pointcut的join point上pointcut表达式与join point相关联Spring中默认使用AspectJ切入点表达式
    • Introduction在类中声明新的方法、域变量甚至是接口实现
    • linking将应用类型或对象和切面链接起来
  • Spring AOP的类型

    • before在连接点之前运行但是无法阻止后续连接点的执行
    • after returning在连接点正常返回之后进行
    • after throwing在链接点抛出异常正常退出之后进行
    • after finally上两种的结合不管连接点是正常退出还是抛出异常退出都会在其之后执行
    • aroundaround可以自定义连接点之前和之后的执行内容其也能够选择时候执行连接点的方法
  • Spring AOP的特点

    • 区别于AspectJ AOP框架Spring AOP框架是基于代理来实现的
    • 对于实现了接口的类Spring AOP通常是通过JDK动态代理来实现的对于没有实现接口的类Spring AOP是通过cglib来实现的
    • 可以强制Spring AOP使用cglib在如下场景
      • 如果想要advise类中方法而该方法没有在接口中定义
      • 如果想要将代理对象传递给一个具有特定类型的方法作为参数
  • Spring AOP的AspectJ注解支持

    • Spring AOP支持AspectJ注解Spring AOP可以解释和AspectJ 5相同的注解通过使用AspectJ提供的包来进行切入点解析和匹配
    • 但是即使使用了AspectJ注解AOP在运行时仍然是纯粹的Spring AOP项目不需要引入AspectJ的编译器和weaver
    • Spring AOP对AspectJ注解支持的开启
      • 通过@EnableAspectJAutoProxy注解会自动的为满足切入点匹配的连接点bean对象创建移动代理对象
      @Configuration
      @EnableAspectJAutoProxy
      class AspectJConfiguration {
          // ...
      }
      
  • 声明Spring AOP切面

    • 在容器中任何bean对象如其类型具有@AspectJ注解将会被自动探知到并且用来配置spring aop
    • 在Spring AOP中aspect其自身是无法作为其他aspect的目标对象的。被标记为@Aspect的类不经标明其为aspect并且将其从自动代理中排除
    @Component // 将该类型声明为bean对象
    @Aspect // 声明切面
    public class ProxyAspect {
    
    }
    
  • 声明Spring AOP切入点

    • 由于Spring AOP仅仅支持方法的连接点故而可以将切入点看做对bean对象方法的匹配
    • Join Point expression的种类
      • execution匹配目标方法的执行可以在括号中接收一个函数签名包含返回类型、函数名和函数参数类型
      // 被@JointPoint注解标注的方法必须具有void的返回类型
      @JoinPoint("execution(* Point.*(..))")
      void methodInjected() {
      
      }
      
      • within:匹配声明在某一特定类中的方法
      @JoinPoint("within(Point)")
      
      • this匹配生成的代理对象为该类型的方法
      • target匹配目标对象为该类型的方法
      • args匹配特定参数的方法
    • Spring AOP同样支持将JoinPoint匹配为具有特定name的Spring bean对象
      @JoinPoint("bean(nameA) || bean(nameB))")
      
  • Spring AOP中的Advice

    • Advice和Pointcut Expresion相关联主要可以分为before、after、around等种类
    • Before
    @Before("execution(* Point.*(..))")
    public void doSomething() {
    
    }
    
    • AfterReturning:
    // AfterReturning支持获取切入点执行后返回的值
    @AfterReturning(
      pointcut="execution(* Point.*(..))",
      returning="retVal")
    public void doSomething(int retVal) {
    
    }
    
    • AfterThrowing:
    @AfterThrowing(
      pointcut="execution(* Point.*())",
      throwing="ex"
      )
    public void doSomething(Throwable ex) {
    
    }
    
    • After:After不管是切入点正常返回还是抛出异常都会执行
    @After("execution(* Point.*())")
    public void doSomething() {
    
    }
    
    • Around:其方法必须会一个Oject类型的返回值并且方法的第一个参数类型是ProceedingJoinPoint
    @Around("execution(* Point.*())")
    public Object doSomething(ProceedingJoinPoint pjp) {
      return isCacheExisted()?returnFromCache():pjp.proceed();
    }