BeanDefinition中的载入与分析-开篇

前面在分析了BeanDefinition的资源定位之后,现在主要分析下BeanDefinition的载入,就是说将一个BeanDifinition转化为Spring框架内部的数据结构的过程,今天这篇文章就是分析这个过程的分析
其实就是说这些BeanDefinition在Ioc容器中通过一个HashMap进行相关的操作来完成的

下面还是从DefaultListAbleBeanFoctory来举例说明,从他的设计入手进行解析

第一步:容器的初始化标记,就是在实例化FileSystemXmlApplication的时候调用了refresh()方法,对ioc容器进行了初始化,也就是在这一步是对BeanFoctory这些基本的数据结构进行了一些基本的处理操作

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
    //在对FileSystemXmlApplicationContext实例化时调用了Refresh()方法
        if (refresh) {
            this.refresh();
        }

    }
    //重点就是Refresh()是ioc容器初始化的一个重要的标识

第二部分:解析refresh()中的具体具体实现部分
refresh方法是在AbstractApplicationContext(其实就是FileASystemXmlApplicationContext的基类)中找到,这个方法主要作用就是MessageSource的注册与PostProcessor的注册
如下是具体的代码解析过程:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            //子类启动RefreshBeanFoctory方法
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                //前面讲到的Process注册
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                //前面讲到MessageSource
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                //注册(Bean)监听
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var9);
                //销毁掉Bean
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }

第三:就是对第二部分的子类启动的RefreshBeanFoctory的追踪
AbstractRefreshableApplicationContext中的refreshBeanFactory方法的解析`

//其实就是在创建一个容器,如果有beanFactory的话,那么就会对他进行摧毁,并且关闭,然后再新建
protected final void refreshBeanFactory() throws BeansException {
    //如果有beanFactory的话,那么就会对他进行摧毁,并且关闭
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
           // 然后再新建
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            this.loadBeanDefinitions(beanFactory);
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

第四:主要讲述下其中主要的类继承以及方法的调用流程

在这里插入图片描述
第五:调用loadBeanFactory()就是一个抽象方法,实际处理在AbstracrXmlApplicationContext中实现

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    //创建一个XMl中的Reader阅读器
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        this.loadBeanDefinitions(beanDefinitionReader);
    }

第六:调用LoadBeanFactory的地方,首先获取到BeanDefinition的定位,然后使用XmlBeanDefinitionReader来读取,实际就是用BeanDefinitionReader来读取的

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    //BeanDefintion的resource资源的获取
        Resource[] configResources = this.getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }

        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }

    }

总结分析:
通过对FileSystemXmlApplicationContext的过程中,通过Ioc容器中的Refresh()方法启动整个BeanDefinition的载入过程的,主要是通过XmlBeanDefintionReader来完成对BeanDefinition的数据结构的读取的,但是实际使用的容器时DefaultListAbleBeanFactory容器,具体的Resource的载入使用XmlBeanDefinitionReader读入BeanDefinition时实现的,以为不同的Spring可以对应不同形式的BeanDefinition,由于这里使用的是XML方式,所以才用的XmlBeanDefinitionReader阅读器来完成数据的加载,其实这个LoadBeanDefinition方法是在其父类就已经做好准备了的

原文链接:加载失败,请重新获取