使用 Spring 时,XML 和注解是使用得最多的两种配置方式,虽然是两种完全不同的配置方式,但对于 IOC 容器来说,两种方式的不同主要是在 BeanDefinition 的解析上。而对于核心的容器启动流程,仍然是一致的。
AbstractApplicationContext
的 refresh 方法实现了 IOC 容器启动的主要逻辑,启动流程中的关键步骤在源码中也可以对应到独立的方法。接下来以 AbstractApplicationContext
的实现类 ClassPathXmlApplicationContext
为主 ,并对比其另一个实现类 AnnotationConfigApplicationContext , 解读 IOC 容器的启动过程。
AbstractApplicationContext.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(); } // ... } }
ApplicationContext 和 BeanFactory 的关系
ClassPathXmlApplicationContext 和 AnnotationConfigApplicationContext 的继承树如下所示。两者都继承自 AbstractApplicationContext 。
ApplicationContext 继承树( 高清大图 )
BeanFactory 继承树( 高清大图 )
ApplicationContext 是 IOC 容器的承载体,而 BeanFactory 是操作这个容器的工具,两者关系紧密,相互协作。 refresh 方法实现了 ApplicationContext 和 BeanFactory 相互协作的主要过程,不同之处主要在子类 AbstractRefreshableApplicationContext 和 GenericApplicationContext 中实现,两者使用的 BeanFactory 都为 DefaultListableBeanFactory , DefaultListableBeanFactory 的定义如下:
DefaultListableBeanFactory :
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
可见 DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory ,意味着是可配置,可遍历的,至于为什么可以,让我们继续往下寻找找答案。
BeanDefinition 的获取
DefaultListableBeanFactory 中使用 Map 结构保存所有的 BeanDefinition 信息:
DefaultListableBeanFactory : private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); ClassPathXmlApplicationContext 中的解析 使用 BeanDefinitionDocumentReader (可参看 DefaultBeanDefinitionDocumentReader.processBeanDefinition 方法) 将 xml 中<strong>本文来源gaodaima#com搞(代@码$网6</strong>的 bean 解析为 BeanDefinition , 然后由 BeanDefinitionRegistry 注册到 BeanFactory 中。 入口: AbstractApplicationContext.refreshBeanFactory (在 refresh 中调用) AnnotationConfigApplicationContext 中的解析 通过 BeanDefinitionScanner 扫描 Bean 声明,解析为 BeanDefinition 并由 BeanDefinitionRegistry 注册到 BeanFactory 中。 入口: AnnotationConfigApplicationContext 的构造函数。 为什么 ClassPathXmlApplicationContext 的入口是在 refreshBeanFactory 方法中 ? AbstractApplicationContext.refreshBeanFactory 定义如下: AbstractApplicationContext : protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException