码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • AOP原理分析《三》- AOP总体流程


    文章结构

      • 总体流程图
        • 介绍后置处理器
          • AnnotationAwareAspectJAutoProxyCreator的结构
        • 找到合适的增强器并创建代理

    总体流程图

    介绍后置处理器

    开启aop后的BeanDefinition的注册在上文已经说明了。

    在注册阶段只是向容器中注册了一个BeanDefinition的定义,而这个BeanDefinition又不是一个简单的BeanDefinition而是实现了一些特殊的接口,
    不妨先了解下这个注册的BeanDefinition的结构。

    AnnotationAwareAspectJAutoProxyCreator的结构

    分析了该bean的体系结构,如下图:

    可以看出实现了SmartInstantiationAwareBeanPostProcessor、InstantiationAwareBeanPostProcessor、BeanPostProcessor等重要的拓展接口,
    那么可以猜测aop功能大致是通过在每个bean初始化前后运行"bean后置处理器"来完成aop的。

    分别介绍一下这几个接口
    (如果方法找不到请下载spring源码全局搜索一下或者找慢点)

    接口起作用的代码位置
    SmartInstantiationAwareBeanPostProcessoraddSingletonFactory方法在第三级缓存这里
    InstantiationAwareBeanPostProcessorresolveBeforeInstantiation方法 或 populateBean方法getBean的实例化前后 或 属性填充
    BeanPostProcessorinvokeInitMethods方法前后在bean初始化前后

    找到合适的增强器并创建代理

    AnnotationAwareAspectJAutoProxyCreator实现了几个特殊的接口,但是观察了对应的实现代码也就只有BeanPostProcessor的
    postProcessAfterInitialization跟目标接近,而我们对AOP逻辑的分析也从这里开始。

    查找增强器并创建代理:

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
    
        // 1、如果不需要代理,则直接返回原始bean就好了
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
    
        // 2、advisedBeans 记录不需要代理的bean
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    
        // Create proxy if we have advice.
        // 3、获取AdvicesAndAdvisors增强,并创建代理    
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
    		// 根据增强器创建代理对象
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            // proxyTypes 缓存了代理结果
    		this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    后文继续分析如何获取增强器

    传送门:保姆式Spring5源码解析

    欢迎与作者一起交流技术和工作生活

    联系作者

  • 相关阅读:
    关于如何检查一个进程是否存活
    OpenCV(三十六):霍夫直线检测
    重庆自考本科一般多久能拿证?
    大数据分析师职业技能提升好考吗?含金量高不高
    Java-Day16 日期和时间相关API、数字格式化相关API
    .NET -- 使用Dump文件分析异常
    字节跳动基础架构编排调度团队论文入选云计算领域顶会 SoCC 2023
    【2022国赛模拟】[SDSC Day5] 毒药——自适应交互、DP
    环模制粒机设计(说明书+CAD)
    自监督学习(一):基于 Pretext Task
  • 原文地址:https://blog.csdn.net/yuchangyuan5237/article/details/126815906
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号