Spring之IOC(简单bean)源码剖析

大家都知道,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的同学应该很容易就会想到这不就是spring的完整的生命周期吗?哈哈

注:上面蓝色字体是用户可选的,只有用户实现其中的接口了才会进行相关处理,还有init-method也是,只有用户指定了对应的属性了才会进行相关流程

总结:本文主要剖析了BeanDefinition的封装(xml转换为BeanDefinition)以及bean的初始化过程(beanDefinition转换为实际的bean以及注册到容器中)的两个主要流程的源码,本文涉及到的只是一个简单bean,后面会对bean依赖进行剖析补充

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