spring源码解析 - aop相关源码分析
2021-03-26 18:26
标签:方法表 业务 过滤 递归 tin text 查找 包装 ali 我们如果善用spring框架的源码设计思路,其实可以写出低耦合、高内聚、兼顾灵活性和扩展性较好的优雅代码,尤其是在做框架或组件设计的时候。今天我们就来分享一个能让我们代码变得优雅的spring核心模块-AOP模块源码设计。 1、切面(Aspect)-----Spring中叫Advisor AbstractAutoProxyCreator 1、Advisor切面设计部分 2、AopProxy动态代理部分 OK, 有了上面两大块的基础了解后,接下来我们进入Spring AOP这块的源码。 注:本文侧重点是分享Spring AOP在源码上的实现,对于使用层面的东西不是本文的重点 ~ 以上就是Spring AOP这块的源码分享,从以上的源码我们不看出几点:1. AOP的本质其实就是指对一类功能增强;2.Spring实现AOP的核心思路是采用动态代理实现;3.所有类似AOP的功能最终都被封装成MethodInterceptor接口,整体的调用链就是递归调用MethodInterceptor.invoke()方法执行相应的拦截处理;4.最后再强调一点,我们使用AOP的最终目的是解耦业务代码和公共的切面处理逻辑,让整个代码简洁、优雅、职责分明、更易于维护和可读。今天就到暂时这里,更多spring源码相关的干货请继续关注! spring源码解析 - aop相关源码分析 标签:方法表 业务 过滤 递归 tin text 查找 包装 ali 原文地址:https://blog.51cto.com/14815984/2533993AOP的基本要素
切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
2、切点(Pointcut)-----一类JoinPoint的集合
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物。AOP通过“切点”定位特定的连接点。连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责切点所设定的查询条件,找到对应的连接点。其实确切地说,不能称之为查询连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。
3、增强(Advice)-----目标类方法的代理方法实现
增强是织入到目标类连接点上的一段程序代码,在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点方位信息和切点信息,我们就可以找到特定的连接点。
4、连接点(Joinpoint)-----被拦截的某个目标方法
程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。
5、目标对象(Target)
增强逻辑的织入目标类。如果没有AOP,目标业务类需要自己实现所有逻辑,而在AOP的帮助下,目标业务类只实现那些非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。SpringAOP的整体架构
整个Spring AOP模块的协作组件,它作为AOP的指挥官角色,统一协作Advisor(切面)和AopProxy(动态代理)这两大核心组件。它的本质是BeanPostProcessor(后置处理器)的一种实现,通过Spring IOC模块来启动运行。它针对的主体是Spring的Bean对象。通过扫描有@Aspect注解的类,构建候选的Advisor切面集合;在Aspect注解类中循环查找没有@PointCut注解的方法封装成Advice对象;通过方法上的注解找到对应的PointCut拦截目标,并把Advisor上的表达式封装到PointCut对象中;然后结合当前的Bean对象的元数据,过滤找到有效的Advisor集合。最后通过beanClass创建针对当前bean的动态代理对象;在代理对象中,动态运行Advisor调用链,完成对当前bean中匹配目标的拦截和增强。
Advisor(切面): 作为AOP中最重要的数据结构,它是aop所有的基础数据的归宿,负责所有的Advice和Pointcut的封装;
PointcutAdvisor:Advisor的扩展组件,它封装Advisor具有的Pointcut能力;
Pointcut(切点):配置Advisor的拦截增强目标,Spring内部最终通过模糊匹配算法,最终定位到具体的拦截目标;
Advice(增强):负责Advisor切面的具体增强业务,它包含AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice、AspectJMethodBeforeAdvice、
AspectJAfterReturningAdvice等具体的增强部件。它们分别一 一对应不同增强类型Around、After、AfterThrowing、Before、AfterReturning 等;
MethodBeforeAdvice:注解Before增强的顶层设计,最终会统一包装成MethodInterceptor对象,提供统一的链式调用能力;
MethodInterceptor:前三种增强类型的基接口,它扩展的invoke方法让Advisor具有了基础的拦截处理能力;
AfterReturningAdvice:注解AfterReturning增强的顶层设计,最终会统一包装成MethodInterceptor对象,提供统一的链式调用能力;
BeanPostProcessor:所有bean后置处理器的基接口,负责定义基础的前、后置处理行为能力;
SmartInstantiationAwareBeanPostProcessor:继承至BeanPostProcessor基接口,扩展了对bean的属性、引用、类型等处理能力;
ProxyFactory:动态代理工厂接口,负责生产创建指定的AopProxy代理对象;
AopProxy:动态代理的基接口,它扩展了JDK内置的动态代理能力和Cglib类代理能力;
JdkDynamicAopProxy:对JDK内置Proxy动态代理的二次封装;
CglibAopProxy:对cglib类动态增强的二次封装;SpringAOP的源码实现
AOP源码入口
AbstractAutowireCapableBeanFactory.initializeBean()实例化bean完成后的相关后置处理
这里是各种BeanPostProcessor后置处理器,针对当前bean做各种扩展和增强的执行入口,包括AbstractAutoProxyCreator、ServletContextAwareProcessor、BootstrapContextAwareProcessor、InitDestroyAnnotationBeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter等。
幂等模式,确保一个增强面只做一次
对候选的Advisor进行过滤,筛选出作用于当前bean上的相关Advisor,并对最终的Advisor的执行顺序进行排序
通过Advisor的准备,对当前bean创建动态拦截代理类
在选用代理模式的时候,spring内部采用这种方式:1、当proxyTargetClass为true时,目标bean实现了接口或只有实现类都采用Cglib做动态代理;2、当proxyTargetClass为false时,目标bean若实现了接口则采用JDK内置代理模式, 若目标bean只有实现类,则采用Cglib类代理模式;3、默认proxyTargetClass为false;
AbstractAutoProxyCreator.buildAdvisors()封装最终的各种切面对象,为后续的链式调用做准备
动态代理对象生成
JDK内置代理创建
Cglib动态代理创建
核心增强业务实现
bean代理对象中,未被拦截的方法直接反射调用,执行方法
ReflectiveMethodInvocation.proceed()链式调用处理核心方法,所有本质AOP的实现(如:注解Transactional、Cacheable和自定义AOP拦截等),都在这里被调用:总结
下一篇:商品活动抽奖概率算法
文章标题:spring源码解析 - aop相关源码分析
文章链接:http://soscw.com/index.php/essay/68231.html