博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码阅读——ClassPathXmlApplicationContext(一)
阅读量:5835 次
发布时间:2019-06-18

本文共 6141 字,大约阅读时间需要 20 分钟。

ClassPathXmlApplicationContext的继承关系

ClassPathXmlApplicationContext继承了AbstractXmlApplicationContext,实现了ApplicationContext接口。BeanFactory是所有容器的顶级接口,spring中所有容器都是基于BeanFactory的。ClassPathXmlApplicationContext继承关系如下图:

clipboard.png

创建ClassPathXmlApplicationContext实例

ClassPathXmlApplicationContext中有多个构造方法,最终都通过如下的构造方法初始化容器:

public ClassPathXmlApplicationContext(          String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)          throws BeansException {     super(parent);     setConfigLocations(configLocations);     if (refresh) {          refresh();     }}

其中,refresh()方法完成了容器的初始化。

refresh()方法的实现分析

refresh()方法的实现代码如下

public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            // 上下文刷新的准备工作,完成一下工作:            //1、设置启动时间、是否关闭和是否激活            //2、在上下文中初始化任何占位符属性资源            //3、验证标记为必需的属性文件是可解析的            prepareRefresh();            // 创建DefaultListableBeanFactory实例,解析xml配置文件,注册bean            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            //对BeanFactory进行各种功能填充            //在此方法中,增加的支持@Qualifier与@Autowired这两个注解            prepareBeanFactory(beanFactory);            try {                // 由子类实现,可进行自定义扩展                postProcessBeanFactory(beanFactory);                // 激活BeanFactory的处理器                invokeBeanFactoryPostProcessors(beanFactory);                // Register bean processors that intercept bean creation.                registerBeanPostProcessors(beanFactory);                // 初始化message资源                initMessageSource();                // 为这个context初始化一个事件广播器                initApplicationEventMulticaster();                // 由子类实现,初始化其他bean                onRefresh();                // 注册已实现ApplicationListener接口的Bean                registerListeners();                // 实例化所有非延迟初始化的单例模式bean                finishBeanFactoryInitialization(beanFactory);                // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知监听者                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();            }        }    }

obtainFreshBeanFactory()方法的实现

此方法主要作用是创建DefaultListableBeanFactory实例,解析xml配置文件,注册bean。内部调用了调用了AbstractRefreshableApplicationContext类的refreshBeanFactory()方法创建bean工厂。refreshBeanFactory()方法实现如下:

protected final void refreshBeanFactory() throws BeansException {        //如果beanfactory存在,销毁所以bean和关闭beanfactory        if (hasBeanFactory()) {            destroyBeans();            closeBeanFactory();        }        try {            //定义beanFactory            DefaultListableBeanFactory beanFactory = createBeanFactory();            beanFactory.setSerializationId(getId());            customizeBeanFactory(beanFactory);            //将bean解析为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);        }    }

refreshBeanFactory()方法中,首先判断是否存在beanfactory,如果存在,销毁所有Bean,关闭beanfactory。createBeanFactory()方法创建一个新的容器。在本方法中,最重要的是loadBeanDefinitions(beanFactory),调用这个方法解析xml配置文件,注册bean。

loadBeanDefinitions(beanFactory)方法的实现如下

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {        // 根据给定的BeanFactory创建一个新的 XmlBeanDefinitionReader        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);        // 根据上下文配置bean definition reader        beanDefinitionReader.setEnvironment(this.getEnvironment());        beanDefinitionReader.setResourceLoader(this);        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));        initBeanDefinitionReader(beanDefinitionReader);        //通过beanDefinitionReader解析xml配置文件,注册bean        loadBeanDefinitions(beanDefinitionReader);    }

在XmlBeanDefinitionReader中实现了loadBeanDefinitions(beanDefinitionReader)方法,代码如下:

//省略了异常处理相关代码,主要逻辑如下public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {        //从encodedResource中得到InputSource和Resource        Set
currentResources = this.resourcesCurrentlyBeingLoaded.get(); InputStream inputStream = encodedResource.getResource().getInputStream(); InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //调用此方法加载BeanDefinition return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); }

doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,从资源文件中读取Document,并且调用registerBeanDefinitions(doc, resource)注册BeanDefinition,省略无关代码,实现如下:

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)            throws BeanDefinitionStoreException {        try {            //从resource中读取得到Document            Document doc = doLoadDocument(inputSource, resource);            //注册BeanDefinition            return registerBeanDefinitions(doc, resource);        }        catch (BeanDefinitionStoreException ex) {            throw ex;        }}

在registerBeanDefinitions(doc, resource)方法中,BeanDefinition的注册时委托给BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法进行注册的。

转载地址:http://nuycx.baihongyu.com/

你可能感兴趣的文章
32、SpringBoot-整合Dubbo
查看>>
python面向对象基础
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
docker 下 安装rancher 笔记
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>
微信小程序蓝牙连接小票打印机
查看>>
C++_了解虚函数的概念
查看>>
全新jmeter视频已经上架
查看>>
Windows 8下如何删除无线配置文件
查看>>
oracle系列(五)高级DBA必知的Oracle的备份与恢复(全录收集)
查看>>
hp 服务器通过串口重定向功能的使用
查看>>
国外10大IT网站和博客网站
查看>>
android第十一期 - SmoothSwitchLibrary仿IOS切换Activity动画效果
查看>>
zabbix 批量web url监控
查看>>
MongoDB CookBook读书笔记之导入导出
查看>>
shell如何快速锁定所有账号
查看>>
HTML 5实现的手机摇一摇
查看>>
此博客不再发表对自己私事的看法
查看>>