Spring的XML解析原理,这一次全搞懂再走( 二 )
然后解析传入的相对路径保存到configLocations变量中 , 最后再调用父类AbstractApplicationContext的refresh方法刷新容器(启动容器都会调用该方法) , 我们着重来看这个方法:
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//为容器初始化做准备prepareRefresh();// 解析xmlConfigurableListableBeanFactory 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();}} }这个方法是一个典型的模板方法模式的实现 , 第一步是准备初始化容器环境 , 这一步不重要 , 重点是第二步 , 创建BeanFactory对象、加载解析xml并封装成BeanDefinition对象都是在这一步完成的 。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory(); }点进去看是调用了refreshBeanFactory方法 , 但这里有两个实现 , 应该进哪一个类里面呢?
文章插图
如果你还记得前面的继承体系 , 那你就会毫不犹豫的进入AbstractRefreshableApplicationContext类中 , 所以在阅读源码的过程中一定要记住类的继承体系 。
protected final void refreshBeanFactory() throws BeansException {//如果BeanFactory不为空 , 则清除BeanFactory和里面的实例if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {//创建DefaultListableBeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());//设置是否可以循环依赖 allowCircularReferences//是否允许使用相同名称重新注册不同的bean实现.customizeBeanFactory(beanFactory);//解析xml , 并把xml中的标签封装成BeanDefinition对象loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);} }
推荐阅读
- 国家工业互联网标识解析二级节点(威海)上线
- 多就是好吗?解析智能手机多摄发展困局
- 新基建下,系统集成商数字化建设及渠道管理深度解析
- 四个维度解析区域发展与治理
- 基于Spring+Angular9+MySQL开发平台
- 智媒视角看深圳用数据解析城市
- “联邦的战斗力量”再现,华硕Z490主板机动战士高达版解析
- 天翼云全国首个工业互联网平台二级解析节点上线
- 在美国当快递小哥赚钱吗?西瓜视频解析除了努力,运气也很重要
- 蚂蚁庄园月有阴晴圆缺答案解析 12月18日今天支付宝蚂蚁庄园答案大全
