Spring Ioc 容器启动流程源码解析

做java开发四年了,很多时候都在想spring究竟是怎么玩转的,当对java有一定深入的理解,我们就需要对spring的源码进行解读,源码的解读过程个人觉得至少要看5遍以上才会不晕车,品读其中的奥妙。

 

IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建、依赖的代码,反转给容器来帮忙实现。

 

一、Spring 核心容器类图

    1、BeanFactory: spring Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,也即 IOC 容器为开发者管理对象 间的依赖关系提供了很多便利和基础服务,在 Spring 中有许多的 IOC 容器的实现供用户选择和使用, 其相互关系如下:

    

    2、BeanDefinition: SpringIOC 容器管理了我们定义的各种 Bean 对象及其相互的关系,Bean 对象在 Spring 实现中是 以 BeanDefinition 来描述的,其继承体系如下:

    

    3、BeanDefinitionReader: Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵 活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过 BeanDefintionReader 来完成,最后看看 Spring 中 BeanDefintionReader 的类结构图:

    

    了解了spring容器的核心类,我现在就迫切的想知道,整个流程是如何串起来的,下面来看看spring webmvc 的启动过程。

 

二、Web IOC 容器初体验

    1、web应用启动的核心之一就是启动了一个servlet来处理我们的请求,那我们熟悉的DispatchServlet 又是如何驱动spring的Ioc容器的,servlet启动肯定是从init()方法开始,最终在FrameWorkServlet的configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac)方法中调用AbstractApplicationContext的refresh()方法,从而驱动Ioc容器初始化,如下图:

 

    2、refresh()方法:其中Ioc容器的初始化就在obtainFreshBeanFactory()方法中

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        //1、调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
        this.prepareRefresh();
        //2、告诉子类启动 refreshBeanFactory()方法,Bean 定义资源文件的载入从
        //子类的 refreshBeanFactory()方法启动
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        //3、为 BeanFactory 配置容器特性,例如类加载器、事件处理器等
        this.prepareBeanFactory(beanFactory);

        try {
                //4、为容器的某些子类指定特殊的 BeanPost 事件处理器
            this.postProcessBeanFactory(beanFactory);
            //5、调用所有注册的 BeanFactoryPostProcessor 的 Bean
            this.invokeBeanFactoryPostProcessors(beanFactory);
            //6、为 BeanFactory 注册 BeanPost 事件处理器.
            this.registerBeanPostProcessors(beanFactory);
            //7、初始化信息源,和国际化相关.
            this.initMessageSource();
            //8、初始化容器事件传播器.
            this.initApplicationEventMulticaster();
            //9、调用子类的某些特殊 Bean 初始化方法
            this.onRefresh();
            //10、为事件传播器注册事件监听器.
            this.registerListeners();
            //11、初始化所有剩余的单例 Bean
            this.finishBeanFactoryInitialization(beanFactory);
            //12、初始化容器的生命周期事件处理器,并发布容器的生命周期事件
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

        来看下spring 基于XML 的IOC容器初始化过程,最终BeanDefinition 被放到了DefaultListableBeanFactory 类中的private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256)中,创建过程如下图:

 

 

    在补充一张spring 基于annotion 的IOC容器初始化过程:

三、spring mvc 启动流程图

    总结:Spring Ioc容器的初始化,不管通过何种途径,spring mvc 的DispatchServlet 还是spring boot run ()方法,最后都调用了AbstractApplicationContext 的refresh(),在通过obtainFreshBeanFactor()方法来初始化Ioc容器。

 

文章详情请点击: http://www.xiaoyuge.com.cn/#/article/detail?articleId=68

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值