Spring XML方式解析配置源码浅分析(ClassPathXmlApplicationContext)

// 创建容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContenx.xml");
// 通过构造方法创建容器执行后续生命周期各自操作
// this.setConfigLocations(configLocations)将当前"applicationContenx.xml" 设置到 org.springframework.context.support.AbstractRefreshableConfigApplicationContext#configLocations作为后续xml文件解析的源
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }

    }

// 通过refresh中this.obtainFreshBeanFactory(); 创建beanFactory并设置相关参数 
    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

        }
    }
/* this.obtainFreshBeanFactory()中
org.springframework.context.support.AbstractApplicationContext#refreshBeanFactory;
org.springframework.context.support.AbstractRefreshableApplicationContext#loadBeanDefinitions
创建XmlBeanDefinitionReader 对配置文件进行解析
*/
    protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            this.loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException var2) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);
        }
    }
// 通过一些列loadBeanDefinitions的重载方法,最终通过org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions转换为Document对象
//再通过org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions中parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)判断是否自定义命名空间,如果是默认则调用this.parseDefaultElement(ele, delegate)否则用delegate.parseCustomElement(ele)解析;
/**
其中自定义命名空间通过传进的命名空间地址获取对应NamespaceHandler地址反射进行创建
一.自定义命名空间规范 不会就抄spring-context包
1.classPath下创建META-INF下创建spring.handlers(配置命名空间解析器) 和 spring.schemas(约束)
2.配置的handlers类继承NamespaceHandlerSupport重写init(),根据自定义标签注册对应的BeanDefinitionParser
3.自定义的标签解析器继承BeanDefinitionParser,对自定义标签进行解析处理
org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve 获取对应的NamespaceHandler
再通过org.springframework.beans.factory.xml.NamespaceHandlerSupport#parse中  this.findParserForElement(element, parserContext)找到对应的BeanDefinitionParser中parse方法进行解析
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值