zoukankan      html  css  js  c++  java
  • 【Spring专场】「AOP容器」不看源码就带你认识核心流程以及运作原理

    前提回顾

    前一篇文章主要介绍了spring核心特性机制的IOC容器机制和核心运作原理,接下来我们去介绍另外一个较为核心的功能,那就是AOP容器机制,主要负责承接前一篇代理模式机制中动态代理:JDKProxy和CglibProxy的功能机制之后,我们开始研究一下如何实现一下相关的AOP容器代理机制的。

    AOP入口机制

    如何实现将Aspectj的动态weave织入到Spring容器的Bean中?

    实现的基本实现原理就是后置处理器:BeanPostProcessor机制,实现动态化植入机制。

    如何实现相关的Aspectj的weave织入时机

    bean在初始化的时候会进行调用对应的BeanPostProcessor的对应的方法会进行织入。

    判断的基本流程

    主要取决于wrapIfNecessary方法:

    判断当前的Bean是AOP的基础设施类型

    如果是基础设施类型,则直接回进行返回该bean对象,不会进行相关的初始化对应的aspectj的动态织入机制。

    如果属于定制化的bean对象类型

    会进行寻找相关的Bean对应的何时的加强通知类。

    如果对应该对象的通知增强数组集合不为空

    则会对该bean对象,额外进行增强操作生成相关的代理对象,并返回该执行之后的对象,否则会直接返回该对象即可。

    筛选何时的通知器

    getAdvicesAndAdvisorsForBean方法是我们筛选Advice增强类的核心方法,主要用于过滤和筛选对应该bean的何时的增强器数组信息。

    查找对应Bean的通知增强器

    主要用于调用AnnotationAwareAspectJAutoProxyCreatorfindCandidateAdvisors()方法,其内部会进行先关的核心构建相关的Aspectj的类的相关实现操作

    构建先关Aspectj类buildAspectJAdvisors方法

    1. 首先先进行获取先关的所有容器的BeanName数据集合
    2. 在根绝上面的BeanName名称集合获取相关的BeanType类型集合
    3. 根据BeanType判断当前的Bean是否属于一个Aspectj的注解.类,如果不是则类不做任何处理。

    构建实际的相关的Advisors类机制

    advisorsFactory.getAdvisors获取通知器

    切点处理

    切点类处理操作到此为止,还不完整接下来才是构建动态代理对象的真正执行操作,

    1. 获取上面操作中获取到的Aspectj类中的除了PointCut注解修饰的其他的方法列表。
    2. 根据对应的Aspectj类和相关的Advisors方法列表,创建相关的Advisor实现类,其中内部会进行遍历相关上一步的方法列表,并且调用对应的方法method对应的getAdvisor方法,建立Advisor对象。
    3. 创建相关的AspectJExpressionPointCut对象,并且从方法里的注解表达式进行解析,这最后设置到对应的门面层的Advisor对象实例。
    4. 实际的Advisor对象实现类对象的实际:InstantitationModelAwarePoincutAdvisorImpl实例,并且调用其内部的instantiateAdvice方法构建通知机制。
    5. 其内部仍然会调用getAdvice方法,并且构建相关的注解的类型创建相应的通知。

    筛选何时的通知器并且执行应用

    findAdvisorsThatCanApply方法

    扩展相关的筛选出的通知器列表,extendAdvisors方法,通知器列表首部添加一个DefaultPointcutAdivosr类型的通知器,也就是ExposeInvocationInterceptor.ADVISOR的实现机制。

    创建代理对象

    • jdk动态代理
    • cglib动态代理
    proxy-target-class

    proxy-target-class的属性值,代表是否可以支持代理实现类,默认采用的false代表着,当bean有实现接口的时候,会直接采用jdk的动态代理机制生成代理对象,如果是true,则代表着使用cglib进行生成代理对象。

    例如:
    <aop:aspectj-autoproxy proxy-target-class = "true" /></aop>
    
    AopProxy接口
    • CglibAopProxy接口实现
    • JdkDynamicAopProxy接口实现

    AOP代理对象调用同类的方法问题解决方案

    expose-proxy作用

    前提是必须要配置相关的expose-proxy属性配置值为true,才会进行暴露对应的代理机制。

    为了解决目标方法调用同对象中的其他方法,其他方法的切面逻辑是无法实现,因为会涉及到相关的this操作而不是proxy对象机制。

    可以实现使用AopContext.currentProxy()强制转换为当前的代理对象。

    拦截器链路执行

    intercept方法机制

    获取相关的对应方法的拦截器栈链路,如果没有获取到相关的缓存链路,则会直接调用相关的getInterceptorsAndDynamicInterceptorAdvice获取先关的拦截器链。

    方法拦截器相关的拦截操作连接点

    会进行先关的PointcutAdvisor类型通知器,这里会调用相关的通知器所持有的切点(Pointcut)对类和方法进行匹配,匹配冲过这说明相关的向当前的方法进行织入逻辑控制。此外还会通过geIntercptors()方法对非MethodIntercptor类型的通知进行转换。返回相关的拦截器数组,并且随后存入缓存中。

    执行目标方法的方式

    如果拦截器为空

    则会直接通过代理机制的反射控制进行调用执行即可。

    如果不为空

    则例如jdkDynamicAutoProxy对象进行调用构建ReflectiveMethodInvocation对象,例如它的process方法启动拦截器栈的invoke方法。

    • invoke:执行拦截器栈
    • invokeJoinpoin():执行目标方法

    处理返回值,并且返回该值。

    极限就是为了超越而存在的
  • 相关阅读:
    LeetCode OJ String to Integer (atoi) 字符串转数字
    HDU 1005 Number Sequence(AC代码)
    HDU 1004 Let the Balloon Rise(AC代码)
    HDU 1003 Max Sum(AC代码)
    012 Integer to Roman 整数转换成罗马数字
    011 Container With Most Water 盛最多水的容器
    010 Regular Expression Matching 正则表达式匹配
    007 Reverse Integer 旋转整数
    006 ZigZag Conversion
    005 Longest Palindromic Substring 最长回文子串
  • 原文地址:https://www.cnblogs.com/liboware/p/15780743.html
Copyright © 2011-2022 走看看