赞
踩
做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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。