前言
IOC的全称是Inversion of Control,可以理解为控制反转,控制的是bean,反转的是bean的生命周期由使用者变为Spring框架。IOC是Spring的核心,使用者无需再手动创建对象,Spring定义出Bean容器的概念,负责管理对象的生命周期,下面结合代码对IOC核心流程进行分析。
Bean容器初始化流程
Bean容器初始化流程,包括bean配置的解析,bean生命周期管理,也是IOC开始的地方。核心流程在AbstractApplicationContext.refresh(),refresh可以理解为刷新,包含两部分,1. 如果有已经存在的那么先销毁;2. 创建新的。下面对refresh的代码函数进行分析。
1.prepareRefresh()
准备,这个方法主要完成一些准备工作,包括容器的状态初始化,环境配置校验
2.obtainFreshBeanFactory()
通知子类完成刷新,主要实现是类AbstractRefreshableApplication,其中核心逻辑是判断当前是否已经有beanFactory,如果有那么先销毁,并且释放所有的bean,然后再创建出一个新的beanFactory
3.prepareBeanFactory()
准备beanFactory,主要工作是将相关实体set到beanFactory,比如classLoader,beanPostProcessor等,beanPostProcessor是spring留出的一个hook,可以让使用者在bean实例化的过程中做定制化,详细可以看`BeanPostProcessor`,提供了实例化bean之前和之后的回调方法。
4.postProcessBeanFactory()
留出给子类修改beanFactory的入口,注意这不是BeanFactory,常见的有GenericWebApplicationContext,会为web环境增加额外bean的scope,我们知道容器原生支持bean的scope是singleton和prototype,显然这对web应用来说是不满足的,所以针对web应用,增加了request,session和global_session,3种类型的bean scope。
5.invokeBeanFactoryPostProcessors()
核心流程参考`PostProcessorRegistrationDelegate`,主要功能是触发所有` BeanFactoryPostProcessor.postProcessBeanFactory()`
6.registerBeanPostProcessor()
注册拦截Bean创建的Bean处理器,即注册BeanPostProcessor,不是BeanFactoryPostProcessor,注意两者的区别,这里仅仅是注册,并不会执行对应的方法,将在bean的实例化时执行对应的方法
7.initMessageSource()
详细作用参考类MessageSource
8.initApplicationEventMulticaster()
初始化事件广播器,Spring提供了事件-监听机制,用于管理对不同事件发生时的处理流程,常见的事件比如容器启动事件,结束事件等。而广播器用来控制和维护监听以及事件。
9.onfresh()
预留给子类扩展
10.registerListeners()
在所有bean中查找listener bean,然后注册到广播器中,spring提供了事件-监听机制,使用者可以注册自己的监听器到spring中。
11.finishBeanFactoryInitialization()
对那些是scope是singleton,且不是抽象类,并且不做懒加载的bean进行初始化,也就是预加载,从而加快该bean首次被调用的响应时间,否则到使用中调用getBean()的时候bean才会被正真的实例化。singleton表示单例,可以进行预加载,protptype作用域就不行。
12.finishRefresh()
初始化生命周期处理器DefaultLifecycleProcessor,DefaultLifecycleProcessor含有start方法和stop方法,spring启动的时候调用start方法开始生命周期, spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,启动有一直运行,如一直轮询kafka启动所有实现了Lifecycle接口的类通过spring的事件发布机制发布ContextRefreshedEvent事件,以保证对应的监听器做进一步的处理,即对那种在spring启动后需要处理的一些类,这些类实现了ApplicationListener<ContextRefreshedEvent> ,这里就是要触发这些类的执行(执行onApplicationEvent方法)另外,spring的内置Event有ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、RequestHandleEvent完成初始化,通知生命周期处理器lifeCycleProcessor刷新过程,同时发出ContextRefreshEvent通知其他监听。
依赖和注入
1.如何实例化bean
Spring对bean进行实例化,同样也提供了两种基础的方案,基于java和基于cglib,默认采用cglib方案 `CglibSubclassingInstantiationStrategy`,通过对Enhancer的使用,基于动态代理生成一个新的类,再通过对构造函数的反射实例化对象。
2.如何注入bean的属性
参考类AbstractAutoWireCapableBeanFactory.populateBean(),其中核心思路是基于name或者基于type的注入,如果冲突可以根据配置选择是否覆盖。实际注入的操作在`InjectionMetadata`,目前支持两种注入,1. 基于Field的注入,也就是通过java反射将实际的对象赋值给字段;2. 方法触发,通过java反射调用方法。当然spring在实际注入之前,还有很多细节操作,比如类型转换,参考接口`TypeConverter`。
总结
Spring依赖注入的核心思路是围绕着Bean展开的,首先是Bean的声明解析,包括基于XML,基于注解,然后是Bean如何实例化和注入,直接相关的有BeanFactory,也就是管理Bean整个生命周期的容器,还有由BeanFactory引申出的BeanFactoryPostProcessor,用于对BeanFactory个性化处理,同样对Bean实例化过程中也有个性化的方案BeanPostProcessor。以及对Bean以及相关依赖进行封装的BeanWrapper。另外对Bean的生命周期管理必然会有很多事件,引申出了监听-事件机制。从逻辑角度来理解Bean的生命周期,能更好的理解IOC的本质。
参考
// 非常详细的代码分析