1.Spring容器实现功能的过程
基本类似的流程都可以划分为两个阶段,即容器启动阶段和Bean实例化阶段。
容器启动阶段:加载配置,分析配置信息,装配到BeanDefinition,其他后处理
Bean实例化阶段:实例化对象,装配依赖,声明周期回调,对象其他处理,注册回调接口。
容器启动阶段:首先会通过某种途径加载Configuration MetaData。大部分情况下,需要依赖某些工具类(BeanDefinitionReader)对加载的Configuration MeData进行解析和分析,并将分析后的信息编组为相应的BeanDefinition,最后把这些保存了bean必要信息的BeanDefinition,注册到相应的BeanDefinitionRegistry,这样启动工作就完成了。
Bean实例化阶段:经过启动阶段,所有Bean定义信息通过BeanDefinition的方式注册到了BeanDefinitionRegistry中。当某个请求方通过容器的getBean方法明确的请求某个对象,或者因依赖关系容器需要隐式调用getBean方法时,就会触发第二阶段的活动。
该阶段,容器会首先检查所请求的对象之前是否已经初始化。如果没有,则会根据注册的BeanDefinition所提供的信息实例化被请求对象,并为其注入依赖。如果该对象实现了某些回调接口,也会根据回调接口的要求来装配它。当该对象装配完毕之后,容器会立即将其返回请求方使用。
隐式调用有两种情况。
对象实例化默认采用延迟初始化。即当对象A要实例化时,但A所依赖的对象B还没被实例化,所以会首先实例化对象B,此时对象B即为隐式调用。再实例化对象A。
ApplicationContext的实现过程也是会遵循两个阶段的原则。只不过是在启动完毕后,立即调用所有bean对象的实例化方法getBean()。也就是类org.springframework.context.support.AbstractApplicationContext的refresh()方法。