
Java
文章平均质量分 89
Java相关的7788
AQin1012
少年有他的山海
展开
-
【数据结构与算法】“黑白标记法”带你彻底吃透二叉树的前中后序遍历(超好记的迭代法模版)
做过二叉树前中后序遍历的同学应该有些印象,这三种遍历方式的递归法非常的简单,并且非常的相似,只需要稍微调整下处理逻辑(这里指将节点值添加进集合)的位置即可。原创 2024-02-20 17:58:11 · 1143 阅读 · 0 评论 -
【Spring源码】0.安装Gradle环境
为什么要安装Gradle呀?~~~Spring 团队考虑由 Maven 切换到 Gradle 的主要原因为了减少构建项目所需的时间。 在开发和测试过程中,等待构建完成所花费的时间增加了修复错误和实现新功能所花费的时间。下载 ⏬ Gradle先上地址--->Gradle | ReleasesFind binaries and reference documentation for current and past versions of Gradle.https://gradle.o原创 2022-04-21 16:35:29 · 242097 阅读 · 0 评论 -
【Spring源码】1.下载与编译
首先我们需要下载一套源码到本地源码下载与编译1. 使用Git clone下载源码安装了Git可以直接clone到本地源码版本选择本来直接clone的最新版本,但是一直报各种错,参考了官方说明才知道最新版本已经需要JDK17了(已哭晕...)https://github.com/spring-projects/spring-framework/wiki/Build-from-Sourcehttps://github.com/spring-projects/spring-framewor原创 2022-04-20 13:44:16 · 1723 阅读 · 1 评论 -
【Spring源码】2.试个水先~Debug找到传说中的三级缓存(图解向,堆图预警)
前言(废话)什么是三级缓存?是为了解决循环依赖?那么三级缓存是怎么解决循环依赖的?不知道你有没有什么刷到过类似的传说中的所谓面试必问的连环夺命call。。。[捂脸.gif]在捂N次脸前,同学别怕、先别捂脸!饭要一口一口吃,肉会一克一克长,知识也要一点一点学,今天这篇文章就带你看下,传说中的三级缓存到底长个啥么模样……当见到了他们真实的样子,就会发现……啊哈~啊哈哈~啊哈哈哈~>>>不就是三个Map吗!?(呃不小心剧透了= =)测试代码【Spring源码】1.下.原创 2022-04-29 14:20:36 · 919 阅读 · 0 评论 -
【Spring源码】3. xml文件如何转换成BeanDefinition(主要涉及prepareRefresh()+ obtainFreshBeanFactory()两个函数,图解向,堆图预警)
一堆图预警~~~通过测试启动类进入ApplicationContext容器设置(解析)配置文件路径setConfigLocations(configLocations); 参数configLocations格式是String[] 进入超级重要的refresh()方法1.准备工作:prepareRefresh()/** * Prepare this context for refreshing, setting its startup date and原创 2022-04-29 13:42:58 · 1178 阅读 · 1 评论 -
【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)
前言(放在开头的废话)不知道你有没有注意过命名空间这个东西,或者你有没有注意过xmlns、xmlns:context、xmlns:xsi(更多瞅下图)...问题来了,这些是啥么?这些是Spring中的命名空间,其主要作用是避免命名冲突,打个比方就是你和张三都有一个叫做heheda的bean,但是由于你们用的是各自的命名空间,就会给你俩的heheda前分别加上表示你俩命名空间的前缀,以免混淆。Spring中主要分两位两种命名空间:默认命名空间和自定义命名空间(函数parseBeanDef原创 2022-05-25 15:57:33 · 239538 阅读 · 0 评论 -
【Spring源码】5.spring的bean工厂准备工作(prepareBeanFactory(beanFactory))
BeanFactory的准备工作,对各种属性进行填充原创 2022-06-02 13:35:44 · 479 阅读 · 0 评论 -
【Spring源码】6. Spring扩展自定义属性编辑器保姆级教程
字符串在编译期间如何转化为指定的类型原创 2022-06-02 14:57:28 · 1040 阅读 · 1 评论 -
【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor
如何添加自定义的BeanFactoryPostProcessor?新建两个类,分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口(任选一个也可以,本文为了介绍全面,两个同时举例🌰)原创 2022-06-08 17:40:09 · 1968 阅读 · 2 评论 -
【Spring源码】8. 捋下invokeBeanFactoryPostProcessors()主要处理流程
看下invokeBeanFactoryPostProcessors()函数的源码同学应该会发现这个方法跟之前文章中提过的getBean ()一样(它不是一个人在战斗)他有很多重载方法=_=,最终执行具体逻辑的方法中也有很多重复的部分,嘿嘿上篇还进行了相关的扩展,这篇文章我们来捋捋这个函数的流程(。・ω・。)ノ...原创 2022-07-21 16:19:39 · 487 阅读 · 0 评论 -
【Spring源码】9. 超级重要的ConfigurationClassPostProcessor
上一篇我们捋了捋invokeBeanFactoryPostProcessors()的整体逻辑,由于ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor所以他会在invokeBeanFactoryPostProcessors()方法中被处理,我们debug到invokeBeanFactoryPostProcessors()方法中.........原创 2022-07-29 13:29:54 · 710 阅读 · 0 评论 -
【Spring源码】10. 递归调用的processConfigurationClass()方法
先创建了一个扫描类依次获取的相关属性为刚刚创建的扫面类赋值lazyInit将要扫描的包统一放入集合中使用创建并设置好参数的扫描器处理这个集合()doScan()在这个方法中,将上一个方法中放置需要扫描的包的集合传入创建好的扫描器进行处理,注册符合要求的BeanDefinition()注册BeanDefinition。.........原创 2022-08-01 18:53:38 · 750 阅读 · 0 评论 -
【Spring源码】11. 我是注解类不?checkConfigurationClassCandidate()注解类判断方法详解
checkConfigurationClassCandidate()方是用来检查给定的BeanDefinition是否是一个配置类的候选者(或一个在配置/组件类中声明的嵌套组件类),并对其进行相应的标记处理的第一步,当然是先获取bean定义信息中的class类名,不符合要求则直接返回false如果上述两种情况都不符合,就直接获取className的MetadataReader实例,读取底层类的完整注解元数据。.........原创 2022-08-01 18:43:31 · 659 阅读 · 0 评论 -
【Spring源码】12. 注册bean处理器registerBeanPostProcessors()
第二步,定义集合并将符合要求的BeanPostProcessor放入相应的集合中。则是在合并处理Bean定义的时候的回调(Spring 内部使用)第一步,去工厂里根据类型扫描,找到所有的实现了。本方法搞定٩(˃̶͈̀௰˂̶͈́)🎉🎉🎉و。方法中,我们调用了各种。处理器,接下来我们来瞅瞅。遍历判断并放入对应的集合。所以最后还需要处理集合。.........原创 2022-08-03 10:57:47 · 586 阅读 · 0 评论 -
【Spring源码】13. 国际化处理initMessageSource()源码解析
负责这块功能的就是下图中红框框圈中的方法~原创 2022-08-12 14:38:48 · 536 阅读 · 0 评论 -
【Spring源码】14. 消息多播器(观察者模式)
本文主要涉及三个方法 initApplicationEventMulticaster()、onRefresh()、registerListeners()原创 2022-09-01 15:36:20 · 991 阅读 · 0 评论 -
【Spring源码】15. Bean的创建过程(1.概述篇)
我们来概述下refresh()中的最后一个也是极其重要的方法finishBeanFactoryInitialization(),它是Spring IOC的核心原创 2022-10-17 14:03:12 · 801 阅读 · 0 评论 -
【Spring源码】16. Bean的创建过程(2)
然后,该BeanDefinition判断是否为非抽象,且单例,且非懒加的BeanDefinition 其中,关于判断的三个函数用于判断这个Bean是否是 "抽象的"原创 2022-10-20 18:00:10 · 788 阅读 · 0 评论 -
【Spring源码】17.创建Bean这篇认真的@(・●・)@
我们先来看看这个传说中的createBean()长什么样(*≧ω≦)~~原创 2022-10-23 11:30:59 · 633 阅读 · 0 评论 -
【保姆级】lookup-method标签实践与分析
** * @Description * @Author aqin1012 AQin. * @Date 2022/8/22 10:25 AM * @Version 1.0 */ public abstract class AnimalAction { /** * 获取执行该动作的动物 * * @return */ public abstract Animal getAnimal();本文就是这两种情况的栗子🌰,感兴趣的同学可以跟着一步一步操作,绝对保姆级教程(不愧是俺(˶‾᷄ ⁻̫ ‾᷅˵))原创 2022-11-04 13:24:52 · 1021 阅读 · 2 评论 -
【保姆级·创建对象】如何利用resolveBeforeInstantiation()在预处理阶段返回一个Bean的实例对象
本文我们来盘盘prepareMethodOverrides()方法后面的resolveBeaforeInstantiation()的函数,看过之前文章介绍的同学应该有印象,它是应用实例化前的前置处理器,是在正式实例化前的一种预处理方式(即在预处理阶段给BeanPostProcessors们一个机会来返回代理来代替真正的实例)所以如果我们想要进入if的逻辑中,就需要同时满足这两个条件,直接用Spring源码debug是不会进入的,所以我们需要创造条件,让程序进入if的逻辑中。原创 2022-11-15 15:12:34 · 1548 阅读 · 7 评论 -
【Spring源码】18. factory-method创建对象关键函数详解:instantiateUsingFactoryMethod()
factoryMethod和args的相关判断,如果没解析过,就获取factoryClass的用户定义类型,因为此时factoryClass可能是CGLIB动态代理类型,所以要获取父类的类型。如果为空的话,就要去找出factoryClass的以及父类的所有方法,进一步找出方法修饰符一致且名字跟工厂方法名字相同的且是bean注解的方法,并放入列表里。如果获取到的候选方法只有一个,且传入的参数为空,且没有设置构造方法参数,就进行一系列的相关参数设置,然后返回BeanWrapperImpl对象。原创 2022-11-23 16:26:08 · 672 阅读 · 0 评论 -
【保姆级·创建对象】如何通过Supplier创建对象
Spring创建对象的主要方式有自定义BeanPostProcessor,生成代理对象InstantiationAwareBeanPostProcessorcreateBean() -> resolveBeforeInstantiation()通过supplier创建对象createBean() -> doCreateBean() -> createBeanInstance() -> obtainFromSupplier()通过FactoryMethod创建对象createBean() -> doCreat原创 2022-12-05 16:44:13 · 652 阅读 · 0 评论 -
【保姆级·创建对象】如何通过factory-method创建对象
这个步骤在createBeanInstance()方法中有使用,我们先来看下这个方法中都干了些啥(。・ω・。)ノ 首先,方法开头确认了beanClass是否被加载(因为只有被加载叻的对象才是可以实例化的)然后,判断当前beanDefinition中是否包含实例供应器,此步骤如果instanceSupplier!=null的话,则会直接通过obtainFromSupplier(instanceSupplier, beanName);方法直接返回一个Bean的包装类BeanWrapper而不会再进行下面的逻辑叻原创 2022-12-06 16:42:08 · 778 阅读 · 0 评论 -
【Spring源码】插播一个创建代理对象的wrapIfNecessary()方法
在文章中,提到过一个方法——wrapIfNecessary(),就是在这个方法中为Bean创建的代理对象,介于篇幅原因,当时并咩有详细🔎分析这个方法,这篇文章我们进去wrapIfNecessary()这个方法中瞅瞅(。・ω・。)ノ。原创 2023-01-29 10:46:25 · 785 阅读 · 0 评论 -
【Spring源码】19. 没合适的构造器?找determineCandidateConstructors()!
上篇介绍了instantiateBean()(其实这个方法在后面还会再次被调用)如果在前两篇的内容结束后都还未获取到构造函数,那么则继续向下执行,调用determineConstructorsFromBeanPostProcessors()方法。原创 2023-01-10 16:46:04 · 622 阅读 · 1 评论 -
【Spring源码】20. MergedBeanDefinitionPostProcessor修改/合并bean定义
随后进入applyMergedBeanDefinitionPostProcessors()方法applyMergedBeanDefinitionPostProcessors()方法中调用MergedBeanDefinitionPostProcessor后置处理器修改/合并bean定义进入bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName)原创 2023-01-10 17:37:37 · 1253 阅读 · 0 评论 -
【保姆级】@PostConstruct & @PreDestroy使用示例
感兴趣的同学可以注意下,上面在处理被@PostConstruct和@PreDestroy注解修饰的代码中并没有出现@PostConstruct和@PreDestroy,出现的是InitAnnotationType和DestroyAnnotationType,那么@PostConstruct和@PreDestroy是在哪里被转换为InitAnnotationType和DestroyAnnotationType的?原创 2023-01-10 17:44:48 · 829 阅读 · 0 评论 -
【Spring源码】AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解
像之前介绍CommonAnnotationBeanPostProcessor一样的,我们进入applyMergedBeanDefinitionPostProcessors()方法中的循环中,当遍历的BeanPostProcessor为AutowiredAnnotationBeanPostProcessor时,就开始了我们这篇文章⁄(⁄ ⁄ ⁄ω⁄ ⁄ ⁄)⁄~~~原创 2023-01-11 14:57:35 · 315 阅读 · 0 评论 -
【Spring源码】21. 初探循环依赖
不同的Bean之间的依赖关系形成了一个闭环(比如ABean依赖了BBean,同时BBean又依赖了ABean),我们把这种依赖关系就称为循环依赖一级缓存 -> 二 级缓存 -> 三级缓存就是往三级缓存中放入创建当前对象lambda表达式,方便后续进行回调调用。原创 2023-01-12 13:25:33 · 601 阅读 · 0 评论 -
【保姆级】手把手Debug循环依赖的整体流程
我们先看一下循环依赖,这样看、或者这样看、一提到循环依赖基本必提三级缓存,本篇又是篇保姆级的Debug教程,详解出现循环依赖Spring处理的全过程,之前也介绍过一些与本篇相关的内容:想瞅瞅三级缓存的庐山真面目可以移步到想了解更多关于三级缓存的相关内容欢迎移步到。原创 2023-01-16 11:22:56 · 240732 阅读 · 10 评论 -
【实践向】当移除了三级缓存……
上面的实践过程直观的证明了一个我们早就知道的结论(˶‾᷄ ⁻̫ ‾᷅˵):如果不存在代理对象,二级缓存就可以解决循环依赖性的问题,但是当存在代理对象的时候,二级缓存则无法完全解决循环依赖,需要引入三级缓存。原创 2023-01-17 14:19:03 · 943 阅读 · 0 评论 -
【分析向】没有三级缓存会导致什么?
通过上篇(【实践向】当移除了三级缓存……)的实践,我们得出的结论是:如果不存在代理对象,二级缓存就可以解决循环依赖性的问题,但是当存在代理对象的时候,二级缓存则无法完全解决循环依赖,需要引入三级缓存那么、在没有三级缓存的情况下,引入代理后为什么会报错?由于我们的代码只修改了两处,但前后出现了不同执行结果,所以我们可以将分析重点🔎放在修改的两处代码上(代码与文章【实践向】当移除了三级缓存……中的修改后的代码一致,想动手实践下的可以去瞅下,本文较长,这里就不贴叻)原创 2023-01-28 13:06:06 · 237746 阅读 · 2 评论 -
【Spring源码】CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解
CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()中一共包含3个方法,上篇文章我们介绍了的第一个方法,它一个父类调用(如下图),其实就是处理@PostConstruct和@PreDestroy这两个注解的这篇我们继续介绍后面两个方法( ̄∇ ̄)原创 2023-01-11 14:58:03 · 637 阅读 · 2 评论 -
【Spring源码】22. 属性填充populateBean()详解
当needsDepCheck为true时,会进行行依赖检查,判断filteredPds是否为空,如果为空会对其进行赋值,最终通过调用checkDependencies()检查pd的setter()方法需要赋值时,pvs中有没有满足pd需求的属性值可供其赋值。前面介绍过的resolveBeforeInstantiation()这个方法中就有类似的代码(这个方法是应用实例化前的前置处理器,给BeanPostProcessors一个机会来返回代理代替真正的实例)有咩有客官觉得if (!原创 2023-01-30 13:40:55 · 1128 阅读 · 1 评论 -
【Spring源码】自动注入·名称:autowireByName()详解
这里的“简单”值类型需要同时满足三个条件:值类型不为Void.class(Void.class!= type)值类型不为void.class(void.class!= type)满足以下条件任意:这里有两个方法需要介绍下(。・ω・。)ノ。原创 2023-01-31 09:57:15 · 698 阅读 · 1 评论 -
【Spring源码】自动注入·类型:autowireByType()详解
进入方法autowireByType()首先获取工厂的自定义类型转换器,如果获取到没有配置自定义类型转换器就使用bw作为类型转换器插播:为什么类型为BeanWrapper的bw可以赋值给类型为TypeConverter的converter?因为BeanWrapper继承了ConfigurablePropertyAccessor,而ConfigurablePropertyAccessor继承了TypeConverter。原创 2023-02-06 17:23:43 · 737 阅读 · 1 评论 -
【Spring源码】属性值的解析与赋值:populateBean().applyPropertyValues()
方法一开始判断传入的PropertyValues是否为空,如果为空则直接返回,不为空则继续后面的处理逻辑判断是否有安全管理器并且bw是否为BeanWrapperImpl的实例,如果都为true则切换为安全上下文继续判断传入的pvs是否是MutablePropertyValues的实例是,进行isConverted()的判断,以免进行重复处理,不是,获取pvs的propertyValue对象数组,并且将其转换为列表。原创 2023-02-07 17:12:06 · 576 阅读 · 0 评论 -
【保姆级】超超超简单的自定义注解实现@Autowired同款功能
对,构造函数,我们把原先构造函数中添加autowiredAnnotationTypes中的注解类换成了我们自定义的注解类AqinAutowired.class,所以在这次的逻辑中,会将被注解AqinAutowired修饰的字段/方法添加进特定存放的集合。着急想看到效果的同学可以直接无脑copy我贴出的代码,先执行成功开心一下(或者直接往下看我的截的执行结果颅内兴奋下也成( ̄∇ ̄)>),我把分析放在最后,有兴趣自行前往观看(。・ω・。)ノ。1个自定义注解类(AqinAutowired.java)原创 2023-02-08 17:01:34 · 907 阅读 · 8 评论 -
【Spring源码】23. 执行初始化逻辑:initializeBean()
遍历该工厂创建的bean的BeanPostProcessors,依次调用当前遍历到的BeanPostProcessor的postProcessBeforeInitialization()方法(这个方法会在初始化Bean前进行调用),将当前BeanPostProcessor应用到给定的Bean实例(由于Bean已经填充了属性,返回的可能是原始Bean的包装器)结果是执行到输出行前,代码停在了initializeBean()方法的断点处,点击继续,执行了输出操作,接着就直接结束了,也就是说,我。原创 2023-02-09 11:05:10 · 722 阅读 · 4 评论