什么是AOP?

在AOP(面向切面编程)之前,不得不提一下OOP(面向对象编程),OOP把业务中的一些实体进行抽象封装,可以更加清晰的处理任务;但同时也有不足,无法定义横向的关系,如那些与业务无关的方法,这就需要AOP辅助,进行拓展,如一些日志功能的编写,可以减少大量代码冗余,减少模块的耦合度。

关于AOP的一些基础概念:

其实就是开启代理功能,同时定义切面类,以及编写切面类内部的切点以及通知

  • JoinPoint连接点:Spring把所有方法都看作连接点
  • PonitCut切点:需要被增强的方法
  • Advice通知:具体的增强行为
  • Aspect切面:通常是一个类,切点和通知的组合,Spring里面用Advisor表示
  • Target目标对象:被增强的方法的类的实例化对象
  • Weaving织入:将通知与切点整合,在编译时进行织入就是静态代理,而在运行时进行织入则是动态代理
  • Proxy代理:用代理对象执行增强方法,可以用JDK或者CGLIB创建代理对象

五种Advice通知

  • Before advice(前置通知):切点前面执行,不能终止后续流程,除非抛异常
  • After returning advice(返回通知):切点正常返回时执行,有异常不执行
  • Around advice(环绕通知):围绕切点前后执行,也能捕获异常处理
  • After advice(后置通知):切点退出时执行,无论是正常退出还是异常退出
  • After throwing advice(异常通知):切点方法抛出异常时执行

AOP的使用场景

日志

事务

AOP底层实现

动态代理

AOP在Spring内部流程

添加组件

@EnableAspectJAutoProxy使用了@Import注解,在调用beanFactoryPostProcessor的时候给Spring容器注册了一个组件AnnotationAwareAspectJAutoProxyCreator,这是一个beanPostProcessor,他会先创建,在创建的时候会获取所有的组件,判断那些需要增强,构建切面类和增强器(增强的方法)

AOP干预bean的生命周期

doCreateBean()实例化之前第一次拦截看看是否返回代理对象

第二次拦截在属性赋值

第三次拦截在初始化initailize之后的后置增强⭐:

  • 创建代理对象,保存代理工厂ProxyFactory(里面有通知方法advisor和一些回调函数)

如何运行对应方法?

把所有增强器adviser编程拦截器intercepter

然后真正执行目标方法和增强,链式调用

链式调用

调用方法会先进入CGLIB的方法回调,然后才会去执行拦截器链;两个MethodInterceptor不同

正常:前置通知 -》方法调用 -》返回通知 -》 后置通知

异常:前置通知 -》方法调用 -》异常通知 -》后置通知 (返回通知因为异常没有返回值并且后续都不执行)