• 【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():执行目标方法

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

    极限就是为了超越而存在的
  • 相关阅读:
    Linux软件安装中RPM与YUM 区别和联系
    Linux分区类型EXT2、EXT3、EXT4详解
    【转】SQLServer数据库还原数据库后因孤立用户问题导致无法登陆的处理
    CVE-2018-8045 Joomla内核SQL注入漏洞
    SQL注入漏洞靶场-sqli-labs学习[1-10]
    SQL注入漏洞
    文件包含漏洞
    CSRF的攻击与防御
    XSS漏洞的基本原理
    Linux高性能服务器编程(一):TCP/IP协议族
  • 原文地址:https://www.cnblogs.com/liboware/p/15780743.html
Copyright © 2020-2023  润新知