zoukankan      html  css  js  c++  java
  • 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依赖进行剖析补充

     
  • 相关阅读:
    Create方法失效而没有提示错误信息
    JS弹出窗口控制
    本周活动
    JavaScript的初步了解
    关于PHP接收文件的资料
    mvc模式改进网站结构
    一周动态
    排序
    Java的内存泄漏
    Android笔记
  • 原文地址:https://www.cnblogs.com/qsky/p/13910726.html
Copyright © 2011-2022 走看看