spring学习(六):spring容器内部工作机制

一、加载配置文件之后的各项操作流程

Spring的AbstractApplicationContextApplicationContext的抽象实现类,该类中的refresh()方法定义了spring容器在加载配置文件之后的各项操作流程,如下所示:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            // 1.初始化beanFactory
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                // 2.调用工厂后处理器
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 3.注册 bean后处理器
                this.registerBeanPostProcessors(beanFactory);
                // 4.初始化消息源
                this.initMessageSource();
                // 5.初始化应用上下文事件广播器
                this.initApplicationEventMulticaster();
                // 6.初始化其他特殊的bean,由具体子类实现
                this.onRefresh();
                // 7.注册事件监听器
                this.registerListeners();
                // 8.初始化所有单实例的bean,使用懒加载模式的除外
                this.finishBeanFactoryInitialization(beanFactory);
                // 9.完成刷新并发布容器刷新事件
                this.finishRefresh();
            } catch (BeansException var9) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var9);
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }
  1. 初始化BeanFactory:根据配置文件实例化BeanFactory,在obtainFreshBeanFactory()方法中,首先调用refreshBeanFactory()刷新,然后调用getBeanFactory()方法获取beanFactory,这两个方法都是由具体子类实现的。在这一步中,spring将配置文件装入到容器的bean定义注册表中(BeanDefinitionRegistry)中,但此时bean还未初始化
  2. 调用工厂后处理器:根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanFactoryPostProcessor接口的bean,并调用其postProcessBeanFactory(ConfigurableListableBeanFactory var1)接口方法
  3. 注册bean后处理器:根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanPostProcessor接口的bean,并将他们注册到容器bean后处理器的注册表中
  4. 初始化消息源:初始化容器的国际化消息资源
  5. 初始化应用上下文事件广播器
  6. 初始化其他特殊的bean:这是一个钩子方法,子类可以借助该方法实现一些特殊的操作。
  7. 注册事件监听器
  8. 初始化所有单实例的bean,使用懒加载模式的bean除外,初始化bean后,将他们放在spring容器的缓存池中
  9. 发布上下文刷新事件,创建上下文刷新事件 ,事件广播器负责将事件广播到每个注册的事件监听器中

二、spring容器 从加载配置文件到创建一个完整的bean的流程如下所示:

  1. ResourceLoader从存储介质中加载spring的配置信息,并使用Resource来表示这个配置文件资源
  2. BeanDefinitionReader读取Resource所指向的配置资源,然后解析配置文件,配置文件的每个<bean>解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中
  3. 容器扫描BeanDefinitionRegistry中的BeanDefinition,使用java反射机制自动识别出bean工厂后处理器(实现了实现了BeanFactoryPostProcessor接口的bean),然后调用这些工厂后处理器对BeanDefinition进行加工,主要完成一下两项工作
    1. 对使用占位符的<bean>元素标签进行解析,得到最终的配置值,这意味着对一些半成品式的BeanDefinition对象进行加工并得到成品的BeanDefinition
    2. 对BeanDefinitionRegistry中的BeanDefinition进行扫描,通过java反射机制找出所有属性编辑器的bean,(实现了java.beans.PropertyEditor接口的bean),并调用InstantiationStrategy着手进行bean实例化的工作
  4. 在实例化bean时,Spring容器使用BeanWrapper对Bean进行封装。BeanWrapper提供了许多java反射操作 bean的方法,它将结合该 bean的BeanDefinition及容器中的属性编辑器,完成bean属性的注入操作
  5. 利用容器中注册的Bean后处理器对已经完成属性设置工作的Bean进行后续加工,直接装配出一个准备就绪的bean
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章