创建 Spring 容器
我们创建 Spring 容器可以通过一行代码进行创建
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
在这个过程中核心就是调用 AnnotationConfigApplicationContext
的构造方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); // 刷新上下文 refresh(); }
Spring 容器创建过程 refresh 方法分析
Spring 容器创建过程主要就是调用 refresh()
方法。我们先一起看看 refresh()
方法具体做了哪些事。具体分为一下几个步骤:
prepareRefresh
预刷新方法,主要是用来初始化和读取上下文配置信息;
obtainFreshBeanFactory()
创建 BeanFactory 对象,其实就是创建一个 Bean 工厂;
prepareBeanFactory(beanFactory)
配置 Bean 工厂,比如设置 ClassLoader、BeanPostProcessor
等;
postProcessBeanFactory
允许子类进行拓展;
invokeBeanFactoryPostProcessors
实例化并调用所有已注册的 BeanFactoryPostProcessor 。调用 BeanFactoryPostProcessor 需要按照顺序调用,优先级是a. 实现_PriorityOrdered_
接口;b. 实现Order
接口; c. 默认。
- registerBeanPostProcessors 注册 Bean 对象的
BeanPostProcessors
;
initMessageSource
初始化 messageSource 其实就是为了支持国际化;
initApplicationEventMulticaster
初始化事件发布器;
onRefresh
模板方法,可以给子类实现,以完成特殊的处理
registerListeners
注册事件监听器,Spring 中的事件机制,其实就是一个典型的观察者模式,这里其实就是注册观察者。
finishBeanFactoryInitialization
完成初始化单实例的非懒加载的 Bean 对象,这里非常关键,对于 Bean 的初始化,属性填充,Aop 等都可以跟着这个方法找到。
finishRefresh
完成初始化,这里会发布一个ContextRefreshedEvent
容器初始化完成事件,以及做一些其他的处理。
对这个过程我们又一个大概的了解过后,我们再来看看 refresh()
方法的定义:
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. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. 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. destroyBeans(); // Reset 'active' flag. 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(); } } }