refresh()方法
首先我们看下这个方法的源码
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 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();
}
}
}
没有一句多余的废话,全是方法调用。
调用的方法虽然很多,但是关键的也就三四个,也涵盖了spring ioc的整个过程,先来看下每个方法的作用:
- 首先是一个锁,这个肯定的,确保只有一个线程来完成初始化后,多线程的话就要乱套了;
- prepareRefresh(); //不重要的方法,主要是用来修改状态,记录容器启动时间的方法;
- obtainFreshBeanFactory(); //重要方法,根据配置文件,将我们要注入的bean转换成BeanDefinition对象;
- prepareBeanFactory(beanFactory); //一般重要方法,添加了几个特殊的BeanPostProcessor,也就是我们说的Bean的后置处理器;
- postProcessBeanFactory(beanFactory); //一般重要方法,我们所有关于ioc过程中的扩展点都在这个方法里了;
- invokeBeanFactoryPostProcessors(beanFactory); //一般重要方法,执行后置处理器的方法;
- registerBeanPostProcessors(beanFactory); //一般重要方法;
- initMessageSource(); //不重要方法,国际化用的;
- initApplicationEventMulticaster(); //不重要方法,事件广播器;
- onRefresh(); //不重要,钩子方法;
- registerListeners(); //不重要,注册监听器;
- finishBeanFactoryInitialization(beanFactory); //最重要的方法,bean的初始化都在这个方法里了;
- finishRefresh(); //不重要,广播完成事件的
所以整个看下来重要的方法有六个,而整个ioc过程可以简化为:
- 通过配置文件将要注入的bean转化成BeanDefinition;
- 通过bean的后置处理器,处理一些创建bean过程中的操作;
- 通过BeanDefinition创建Bean实例,并保存在一级缓存Map中。