首页 > 编程语言 > 详细

Spring之IOC源码剖析

时间:2020-11-01 22:00:39      阅读:46      评论:0      收藏:0      [点我收藏+]

大家都知道,Spring的两大核心思想:1、IOC;2、AOP。本文主要对Spring的IOC源码进行剖析,AOP源码下一篇文章会进行剖析

首先咱么你先写一个简单的demo进行源码调试:

技术分享图片

 

 

 技术分享图片

 

 

 技术分享图片

 

 

 debug模式运行代码在org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext的够构造方法中打断点

技术分享图片

 

继续跟进

 

 技术分享图片

 

 

 可以看到这里组主要就做两件事:1、解析我们传进来的配置文件路径信息;2、调用刷新方法;

接下来我们重点关注一下刷新方法

技术分享图片

 

 

 进入到这个方法中我们就会惊奇的发现,这里面全是方法调用,没有一行多余的代码总共做了十二件事,图中都分别进行了注释。但本文主要看的是第二和第十一步的源码,其他的可以自行进行查看。

 2、获取BeanFactory并将beanDefinition注册到注册器中去

进入org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory 中

技术分享图片

 

 

 

可以看到这里主要做两件事:1、刷新beanFactory;2、获取BeanFactory;

接下来我们继续进入org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory中

技术分享图片

 

 

 可以发现这里也主要做三件事图片中都做了注释,我们重点关注一下加载beanDefinitions

进入org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions方法中

技术分享图片

 

 

 

可以看到这里主要是构建一个beanDefinitionReader对象然后调用重载方法,继续进入重载方法:

技术分享图片

 

 

 可以看到这里主要解析路径配置位置,然后使用reader进行加载beanDefinition。

接下来我们继续进入org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions方法

技术分享图片

 

 

 这里会进行一堆的重载方法最后进入到

技术分享图片

 

 

 继续跟进,进入org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions方法中

继续跟进进入org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions

技术分享图片

 

 

 之后又调用org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions方法

继续跟进

技术分享图片

 

 

 从注释上我们可以看到这里才是真正的将xml转换为beanDefinition的地方,我们继续跟进注册BeanDefinition方法

继续跟进org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions方法

技术分享图片

 

 

 可以 看到这里是按照约定转换BeanDefinition。

继续跟进org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions方法

技术分享图片

 

 

 从注释上我们可以知道这里就是注册beans标签下的元素

我们重点关注一下org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions方法

技术分享图片

 

 

 进入org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement

技术分享图片

 

技术分享图片

 进入org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition方法

技术分享图片

 

 

 继续进入org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition方法

技术分享图片

 

 

 进来之后发现一堆判断,但最终将这个BeanDefinition放入了map中

技术分享图片

 

 

 到这里,BeanDefinition的注册就结束了

接下来我们回到org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory方法中继续看看是如何获取BeanFactory的

技术分享图片

 

 

 进入org.springframework.context.support.AbstractRefreshableApplicationContext#getBeanFactory方法中

技术分享图片

 

 

 到这里咱们注册beanDefinition以及获取BeanFactoryy就完了,接下来继续往下看

我们这里可以看到beanDefinition的加载以及注册主要要做的是:

(1)、通过给定路径转换为能加载BeanDefinition的Resource

(2)、使用Resource把xml转换为BeanDefinition对象

(3)、将转换后的BeanDefinition注册(存入map中)

 

 

 

 

 

11、初始化?懒加载的单例bean,并填充属性等

进入org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization方法

技术分享图片

 

 

 可以看到这里主要就是要对非延迟加载的对象进行实例化

继续进入org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons方法

技术分享图片

 

 

 可以看到这里主要就做两件事:1、获取到咱们再第二步已经注册到容器中的BeanDefinition名称列表;2、遍历每个名称调用getBean方法

我们继续跟进,进入org.springframework.beans.factory.support.AbstractBeanFactory#getBean方法

技术分享图片

 

 

 继续跟进org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法

技术分享图片

 

 

 继续进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton方法

技术分享图片

 

 

 继续进入org.springframework.beans.factory.ObjectFactory#getObject方法

技术分享图片

 

 

 再继续进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean方法中

技术分享图片

 

 

 通过注释,咱们好像想起了springbean声明周期里的一些信息哦,比如与实例化bean、填充属性、postProcessor等。

那这是不是意味着从这里开始就进入了bean的申明皱起了呢?别着急,我们慢慢往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法

技术分享图片

 

 

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance方法

技术分享图片

 

 

 继续进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean方法

 技术分享图片

 

 

 继续进入org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate方法

技术分享图片

 

 

 进入org.springframework.beans.BeanUtils#instantiateClass方法中

技术分享图片

 

 

 可以看到这里就是使用反射创建了一个bean的实例

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory方法

技术分享图片

 

 

 可以看到这里主要就是判断缓存里有没有当前实例化的beanFactory,如果没有就放入缓存中

技术分享图片

 

 

 可以看到spring使用了三级缓存对bean创建过程进行缓存(主要是解决bean的循环依赖问题)

我们继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean方法

技术分享图片

 

 

 从注释中可以知道这个方法主要是填充bean的属性,继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues方法

技术分享图片

 

 

 技术分享图片

 

 

 可以看到这里主要就是获取到bean的属性配置的值然后使用BeanWrapper进行赋值

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean方法

技术分享图片

 

 

 通过注释我们可以知道这里主要是对bean进行实例化,应用工厂的回调、初始化方法以及beanPost处理器

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

技术分享图片

 

 

 可以看到这里主要就是进行一些判断看是否实现了一些Aware,然后进行相应进行处理

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization方法

技术分享图片

 

 

 可以看到这里主要就是对BeanPostProcessor进行处理。

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean中继续往下看

技术分享图片

 

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods方法

 技术分享图片

 

 

 

 技术分享图片

 

 

 这里的话主要就是判断是否实现接口,如果实现了的话就需要调用一下afterPropertiesSet方法,然后再看看自己有没有定义init方法,如果定义了需要调用一下

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法

技术分享图片

 

 

 这里也是主要对BeanPostProcessor的一些处理

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中继续往下看

进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)方法

技术分享图片

 

 

 技术分享图片

 

 

 可以看到这里主要是从缓存中获取已创建的实例,也可以从早期对象缓存中获取到对象(循环依赖),如果在早期对象缓存中获取到对象之后需要把factory缓存移除

回到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary方法中

技术分享图片

 

 

 可以看到这里主要判断是否是单例且有指定销毁方法,如果有的话就创建一个适配器并记录下来

回到org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton中继续往下看

技术分享图片

 

 

 进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton方法中

技术分享图片

 

 

 看可以看到这里主要就是吧把当前实例翻入到单例缓存中,并把之前设置的早期单例对象和工厂缓存移除

到这合理bean的创建(获取)的过程就结束了,接下来我们总结一下在这个过程中都做了什么事

  • 实例化bean
  • 设置bean的属性
  • BeanNameAware的setBeanName?法处理
  • BeanFactoryAware的setBeanFactory?法处理
  • ApplicationContextAware的setApplicationContext?法处理
  • BeanPostProcessor的预初始化?法处理
  • InitializingBean的afterPropertiesSet?法处理
  • 定制的初始化?法init-method处理
  • BeanPostProcessor的后初始化?法

 

 

Spring之IOC源码剖析

原文:https://www.cnblogs.com/qsky/p/13910726.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!