code-learning/spring/48-Spring 源码分析-AOP 源码简单导读.md

198 lines
9.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 精尽 Spring 源码分析 —— AOP 源码简单导读
# 1. 前置内容
Spring AOP 是基于 Spring IoC 机制来实现的,所以建议对 IoC 的源码有一定的了解。
当然,一般情况下,也是先看完 IoC 相关的源码,在来看 AOP 的源码。
# 2. 如何调试
① 调试基于 `@Aspect` 注解的 AOP 的流程
可调试 `org.springframework.aop.aspectj.autoproxy.AspectJAutoProxyCreatorTests` 这个单元测试里的方法。
# 3. 推荐资料
【必读】首先推荐的是《Spring 源码深度解析》的 [「第7章 AOP」](https://svip.iocoder.cn/Spring/aop-simple-intro/#) 章节。
因为 Spring 静态 AOP 实际场景下,使用较少,胖友可以选择性看看。感兴趣的话,可以对 Java Instrumentation 机制做一定的了解。目前主流的链路追踪系统的 Java Agent 都是基于它来实现的。
然后,也推荐看看五月的仓颉关于 AOP 的两篇文章:
- [《【Spring源码分析】AOP源码解析上篇](https://www.cnblogs.com/xrq730/p/6753160.html) ,对 Spring AOP XML 配置的方式进行源码解析。
- [《【Spring源码分析】AOP源码解析下篇](https://www.cnblogs.com/xrq730/p/6757608.html) 内容上和《Spring 源码深度解析》的 [「第7章 AOP」](https://svip.iocoder.cn/Spring/aop-simple-intro/#) 章节,作为互为补充噶。
再然后,也非常推荐田小波关于 AOP 的四篇文章,非常**细致**,特别是对 AOP 的概念解释以及流程的拆分上:
- [《Spring AOP 源码分析系列文章导读》](https://www.tianxiaobo.com/2018/06/17/Spring-AOP-源码分析系列文章导读/)
- [《Spring AOP 源码分析 - 筛选合适的通知器》](https://www.tianxiaobo.com/2018/06/22/Spring-AOP-源码分析-拦截器链的执行过程/)
- [《Spring AOP 源码分析 - 创建代理对象》](https://www.tianxiaobo.com/2018/06/20/Spring-AOP-源码分析-创建代理对象/)
- [《Spring AOP 源码分析 - 拦截器链的执行过程》](https://www.tianxiaobo.com/2018/06/22/Spring-AOP-源码分析-拦截器链的执行过程/)
再再然后,还会灰常推荐 JavaDoop 关于 AOP 的一篇文章,看着大气:
- [《Spring AOP 源码解析》](https://www.javadoop.com/post/spring-aop-source)
最后,推荐一些和 AOP 相关的有趣的文章:
- [《Spring AOP,AspectJ, CGLIB 有点晕》](https://www.jianshu.com/p/fe8d1e8bd63e)
- [《Cglib 与 JDK 动态代理的运行性能比较》](https://www.cnblogs.com/haiq/p/4304615.html)
- [《Spring AOP 源码解析》](https://www.javadoop.com/post/spring-aop-source)
# 4. 后置内容
看完 Spring AOP 之后,当然是看 Spring Transaction 啦。
哈哈哈哈,和我们日常开发,息息相关。
# 5. 重要的类
> 老艿艿:本小节,就是艿艿简单的笔记,可以忽略。嘿嘿。后面,在找时间完善下。
核心流程如下图:
> FROM 《Spring 源码深度解析》
>
> [![核心流程](48-Spring 源码分析-AOP 源码简单导读.assets/02.png)](http://static.iocoder.cn/images/Spring/2020-01-01/02.png)核心流程
## 5.1 aopalliance
对应 `org.aopalliance` 包。
Spring 对 AOP 联盟接口的变种。
- Advice
- Interceptor
- MethodInterceptor
- Joinpoint ,连接点接口。每个方法,都对应一个 Joinpoint 对象。
- Invocation ,调用接口。
- MethodInvocation ,方法调用接口。
- ProxyMethodInvocation ,代理方法调用接口。在根目录的包里。
- ReflectiveMethodInvocation ,反射方法调用实现类。在
```
framework
```
包里。
- CglibMethodInvocation ,基于 CGLIB 方法调用实现类。在 `framework` 包里。
- Advice ,定义的横切逻辑。在如下几个时机,可以进行执行:
- Before :在目标方便调用前执行通知。
- After :在目标方法完成后执行通知。
- After Returning 在目标方法执行成功后,调用通知。
- After Throwing :在目标方法抛出异常后,执行通知。
- Around :在目标方法调用前后均可执行自定义逻。
## 5.2 config
对应 `org.springframework.aop.config` 包。
AopNamespaceHandler ,对 `<aop:/>` 命名空间的处理器。
- AspectJAutoProxyBeanDefinitionParser ,将 `<aop:aspectj-autoproxy/>` 标签,解析成 BeanDefinition 的解析器。
- ScopedProxyBeanDefinitionDecorator
- ConfigBeanDefinitionParser
- SpringConfiguredBeanDefinitionParser
## 5.3 framework
对应 `org.springframework.aop.framework` 包。
AutoProxyCreator 整体类图如下:
[![AutoProxyCreator 类图](48-Spring 源码分析-AOP 源码简单导读.assets/01.png)](http://static.iocoder.cn/images/Spring/2020-01-01/01.png)AutoProxyCreator 类图
- AbstractAutoProxyCreator ,自动代理构造器抽象类。
- `#wrapIfNecessary(Object bean, String beanName, Object cacheKey)` 方法,如果需要,将制定 Bean 对象包装成 **Proxy 代理**对象。
- `#createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource)` 方法,创建 **Proxy 代理**对象。
- AbstractAdvisorAutoProxyCreator ,基于 Advisor 的 自动代理构造器抽象类。
- `#findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName)` 方法,获得 Bean 对象**可使用**的 Advisor 集合,是从 `candidateAdvisors` 参数中筛选出来的。
- `#getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource)` 方法,获得 Bean 对象**可使用**的 Advisor 集合。
- AnnotationAwareAspectJAutoProxyCreator ,支持 AOP 注解的,基于 AspectJ 的代理自动构造器。
- ProxyFactory ,创建 Proxy 的工厂类。
- DefaultAopProxyFactory ,默认 ProxyFactory 实现类。
- AopProxy AOP 代理接口,创建对应的代理对象。
- 它有两个子类:
- JdkDynamicAopProxy ,基于 JDK 的 AOP 代理实现类。
- `#invoke(Object proxy, Method method, Object[] args)` 方法,实现 InvocationHandler 的接口方法,执行代理的调用。【重要】
- ObjenesisCglibAopProxy ,基于 CGLIB 的 AOP 的代理实现类。
- `#getProxy(ClassLoader classLoader)` 方法,创建对应的代理对象。
- AopContext AOP 上下文,基于 ThreadLocal 实现。
- AdvisorChainFactory Advisor 调用链工厂接口,用于获取每个方法调用时的调用链。
- `#getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass)` 方法,获得指定方法拦截的拦截器链。
- DefaultAdvisorChainFactory ,默认实现类。
- ProxyMethodInvocation ,代理方法调用接口。
- ReflectiveMethodInvocation ,基于反射的方式,代理方法调用实现类。
- `#proceed()` 方法,执行方法。基于递归的方式,调用每个拦截器链中的拦截器,最后调用真正的方法。
- `#invokeJoinpoint()` 方法,执行真正的方法,即切点的方法。
- CglibMethodInvocation ,基于 CGLIB 的方式,进一步优化调用的实现类。
- 各种情况下,调用:
- MethodBeforeAdviceInterceptor
- AfterReturningAdviceInterceptor
- AspectJAroundAdvice
- AspectJAfterAdvice
- AspectJAfterThrowingAdvice
- ThrowsAdviceInterceptor
## 5.4 aspectj
对应 `org.springframework.aop.aspectj` 包。
- ReflectiveAspectJAdvisorFactory
- BeanFactoryAspectJAdvisorsBuilder
- `#buildAspectJAdvisors()` 方法,构建**所有** @Aspect 注解类的增强方法对应的 Advisor 对象。
- AnnotationAwareAspectJAutoProxyCreator
- `#findCandidateAdvisors()` 方法,获得**所有**增强方法对应的 Advisor 对象。
- InstantiationModelAwarePointcutAdvisorImpl
- AbstractAspectJAdvice ,基于 AspectJ ,实现 Advice 接口的 Advice 抽象类。
- 有如下几个子类:
- AspectJAroundAdvice
- AspectJMethodBeforeAdvice
- AspectJAfterAdvice
- AspectJAfterReturningAdvice
- AspectJAfterThrowingAdvice
- 通过 `ReflectiveAspectJAdvisorFactory#getAdvice(...)` 方法,构建 AbstractAspectJAdvice 对象。
- 通过 `#invokeAdviceMethodWithGivenArgs(Object[] args)` 方法,执行增强 Advice 的方法。【重要】
## 5.5 interceptor
对应 `org.springframework.aop.interceptor` 包。
- ExposeInvocationInterceptor
## 5.6 scope
对应 `org.springframework.aop.scope` 包。
## 5.7 support
对应 `org.springframework.aop.support` 包。
## 5.8 target
对应 `org.springframework.aop.target` 包。
提供多种 TargetSource 的实现类,而 TargetSource 可以理解成 Target 的数据源,可以根据每次方法调用,返回相同或不同的 Target 对象。可以选择性看看,感兴趣的胖友,可以看看 [《spring-aop组件详解——TargetSource目标源》](https://my.oschina.net/lixin91/blog/688188) 。
## 5.9 根目录
对应 `org.springframework.aop` 包的根目录。
- Pointcut ,切点接口,用于选择连接点。
- 其定义了两个接口方法,分别返回:
- ClassFilter ,匹配哪些类。
- MethodMatcher ,匹配哪些方法。
- AspectJExpressionPointcut AspectJ 的切点表达式。