Spring
源码 - 容器刷新Spring版本:5.3.13-release
IOC(Inversion Of Control)
思想–控制反转1、控制反转:
Spring
进行管理。2、使用IOC
的目的:
3、IOC
是一种思想,DI
就是对IOC
的一种实现方式:
DI(Dependency Injection)
依赖注入:容器能知道哪个组件(类)运行的时候,需要另外一个类(组件);容器通过反射的形式,将容器中准备好的的Bean
实例对象注入(利用反射给属性赋值)到实例中去。只要是容器管理的组件,都能使用容器提供的强大功能。
Spring
中的IOC
接口1、IOC
思想是基于IOC
容器完成,IOC
容器底层就是对象工厂。
2、Spring
提供IOC
容器实现的两种方式:
BeanFactory
接口:IOC
容器最基本的实现方式,是Spring
内部使用的接口,供Spring
内部使用。在加载配置文件的时候,不会去立即创建配置文件中配置的对象,而是在获取的或使用对象的时候创建对象。ApplicationContext
接口:BeanFactory
的子接口,提供了比BeanFactory
更强大的功能。加载配置文件的时候就创建配置文件中声明的对象。在实际开发中,开发人员一般都是实现ApplicationContextAware
接口,通过ApplicationContext
去获取容器中的Bean
。AbstractApplicationContext#refresh()
Spring的容器刷新尤为重要,容器刷新的源码为AbstractApplicationContext#refresh()
。
AbstractApplicationContext#refresh()
源码:
@Override public void refresh() throws BeansException, IllegalStateException { // 进入同步代码块, 保证线程安全 synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // Prepare this context for refreshing. // 准备刷新上下文环境。作用就是初始化一些状态和属性, 后后续的工作做准备 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 创建容器对象 : DefaultListableBeanFactory // 加载 xml 配置文件或者配置类的属性到当前 beanFactory 中。最重要的就是 BeanDefinition ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // beanFactory的准备工作。对各种属性进行填充 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 子类覆盖方法做额外处理, 此处我们自己一般不做任何扩展工作。默认没有实现。但是可以查看 web 中的代码, 是有具体实现的。 // 这个方法是模板方法设计模式的体验, 默认无任何实现, 预留给子类扩展使用 postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. // 调用各种 beanFactory 处理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册 Bean 处理器。这里只是单纯的注册功能, 真正调用的是 getBean 方法 registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // Initialize message source for this context. // 为上下文初始化 message 源, 即不同语言的消息体, 做国际化处理。 initMessageSource(); // Initialize event multicaster for this context. // 初始化事件监听多路广播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 预留给子类, 用于初始化其他的 Bean onRefresh(); // Check for listener beans and register them. // 在所有注册的 Bean 中查找 listener beans 并注册到消息消息广播中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 初始化剩下的单实例 Bean(非惰性) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成容器刷新。通知生命周期处理器 lifecycle processor 刷新过程。同时发出 ContextRefreshEvent 告知别人容器已完成刷新。 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. // 防止 已经创建的 Bean 占用资源, 在异常处理中, 销毁在异常之前创建的单例 Bean destroyBeans(); // Reset 'active' flag. // 重置容器 active 标志为 false 状态 cancelRefresh(ex); // Propagate exception to caller. // 抛出异常 throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); contextRefresh.end(); } } }
refresh()
中一共12个方法:
prepareRefresh()
: 准备刷新上下文环境。作用就是初始化一些状态和属性, 后后续的工作做准备。obtainFreshBeanFactory()
:字面意思是获取新鲜的BeanFactory
,这里获取到的BeanFactory
是DefaultListableBeanFactory
。获取到BeanFactory
之后ApplicationContext
就具备了BeanFactory
的各项功能,可以对Bean
进行各种基础操作。prepareBeanFactory()
:BeanFactory
的准备工作。对各种属性进行填充。postProcessBeanFactory()
:对获取的BeanFactory
做后置增强处理,默认没有实现,子类覆盖方法做额外处理。但是在WEB
中这里是有具体实现的。模板方法设计模式。invokeBeanFactoryPostProcessors()
:调用各种BeanFactory
增强处理器BeanFactoryPostProcessor
及其子接口BeanDefinitionRegistryPostProcessor
。注意,这里调用的各种BeanFactory
的增强处理器是在Bean
实例化之前。registerBeanPostProcessors()
:注册BeanPostProcessor
处理器。这里只是单纯的注册功能, 真正调用的是 getBean()
方法。initMessageSource()
:为上下文初始化Message
源, 即不同语言的消息体做国际化处理。initApplicationEventMulticaster()
:初始化事件监听多路广播器。onRefresh()
:预留给子类, 用于初始化其他的 Bean。registerListeners()
:在所有注册的Bean
中查找listener beans
并注册到消息消息广播中。finishBeanFactoryInitialization()
:初始化剩下的单实例Bean
(非惰性)。finishRefresh()
:完成容器刷新。通知生命周期处理器lifecycle processor
刷新过程。同时发出 ContextRefreshEvent
告知别人容器已完成刷新。由于这里总共有12个方法,源码篇幅较多,所以分为12篇分析每个方法的源码。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。