1.通过前面4篇文章对Spring IoC容器的源码分析,我们已经基本上了解了Spring IoC容器对Bean定义资源的定位、读入和解析过程,同时也清楚了当用户通过getBean方法向IoC容器获取被管理的Bean时,IoC容器对Bean进行的初始化和依赖注入过程,这些是Spring IoC容器的基本功能特性。Spring IoC容器还有一些高级特性,如使用lazy-init属性对Bean预初始化、FactoryBean产生或者修饰Bean对象的生成、IoC容器初始化Bean过程中使用BeanPostProcessor后置处理器对Bean声明周期事件管理和IoC容器的autowiring自动装配功能等。
2.Spring IoC容器的lazy-init属性实现预实例化:
通过前面我们对IoC容器的实现和工作原理分析,我们知道IoC容器的初始化过程就是对Bean定义资源的定位、载入和注册,此时容器对Bean的依赖注入并没有发生,依赖注入主要是在应用程序第一次向容器索取Bean时,通过getBean方法的调用完成。
当Bean定义资源的
下面我们通过代码分析容器预实例化的实现过程:
(1).先从IoC容器的初始会过程开始,通过前面文章分析,我们知道IoC容器读入已经定位的Bean定义资源是从refresh方法开始的,我们首先从AbstractApplicationContext类的refresh方法入手分析,源码如下:
[java]
- //容器初始化的过程,读入Bean定义资源,并解析注册 public void refresh() throws BeansException, IllegalStateException {
- synchronized (this.startupShutdownMonitor) { //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
- prepareRefresh(); //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
- //子类的refreshBeanFactory()方法启动 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- //为BeanFactory配置容器特性,例如类加载器、事件处理器等 prepareBeanFactory(beanFactory);
- try { //为容器的某些子类指定特殊的BeanPost事件处理器
- postProcessBeanFactory(beanFactory); //调用所有注册的BeanFactoryPostProcessor的Bean
- invokeBeanFactoryPostProcessors(beanFactory); //为BeanFactory注册BeanPost事件处理器.
- //BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件 registerBeanPostProcessors(beanFactory);
- //初始化信息源,和国际化相关. initMessageSource();
- //初始化容器事件传播器. initApplicationEventMulticaster();
- //调用子类的某些特殊Bean初始化方法 onRefresh();
- //为事件传播器注册事件监听器. registerListeners();
- //这里是对容器lazy-init属性进行处理的入口方法 finishBeanFactoryInitialization(beanFactory);
- //初始化容器的生命周期事件处理器,并发布容器的生命周期事件 finishRefresh();
- } catch (BeansException ex) {
- //销毁以创建的单态Bean destroyBeans();
- //取消refresh操作,重置容器的同步标识. cancelRefresh(ex);
- throw ex; }
- } }
在refresh方法中ConfigurableListableBeanFactorybeanFactory = obtainFreshBeanFactory();启动了Bean定义资源的载入、注册过程,而finishBeanFactoryInitialization方法是对注册后的Bean定义中的预实例化(lazy-init=false,Spring默认就是预实例化,即为true)的Bean进行处理的地方。
(2).finishBeanFactoryInitialization处理预实例化Bean:
当Bean定义资源被载入IoC容器之后,容器将Bean定义资源解析为容器内部的数据结构BeanDefinition注册到容器中,AbstractApplicationContext类中的finishBeanFactoryInitialization方法对配置了预实例化属性的Bean进行预初始化过程,源码如下:
[java]- //对配置了lazy-init属性的Bean进行预实例化处理 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
- //这是Spring3以后新加的代码,为容器指定一个转换服务(ConversionService) //在对某些Bean属性进行转换时使用
- if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
- beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
- } //为了类型匹配,停止使用临时的类加载器
- beanFactory.setTempClassLoader(null); //缓存容器中所有注册的BeanDefinition元数据,以防被修改
- beanFactory.freezeConfiguration(); //对配置了lazy-init属性的单态模式Bean进行预实例化处理
- beanFactory.preInstantiateSingletons(); }
- ConfigurableListableBeanFactory是一个接口,其preInstantiateSingletons方法由其子类DefaultListableBeanFactory提供。 (3).Defa