spring容器启动的加载过程(二)

第六步:

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory();//具体实现调用子类容器的refreshBeanFactory()方法 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } ... protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException; }

第七步:

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

/** Bean factory for this context */
    private DefaultListableBeanFactory beanFactory;

    protected final void refreshBeanFactory() throws BeansException {
        //如果已经有beanfactory了,则销毁所有的bean,关闭beanfactory
        if (hasBeanFactory()) {  
            destroyBeans();
            closeBeanFactory();
        }
        try {
            //得到一个默认的DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            //对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等 
            customizeBeanFactory(beanFactory);
            //调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器  
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
    
    //创建beanfactory
    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    
    ...
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException; }

第八步:

    
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {


    /** Default config location for the root context */
    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

    /** Default prefix for building a config location for a namespace */
    public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

    /** Default suffix for building a config location for a namespace */
    public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
    
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
         //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源  
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context's
        // resource loading environment.
        //设置环境
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        //为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的祖先父类AbstractApplicationContext,他继承DefaultResourceLoader,因此容器本身也是一个资源加载器  
        beanDefinitionReader.setResourceLoader(this);
        //为Bean读取器设置SAX xml解析器 
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // Allow a subclass to provide custom initialization of the reader,
        // then proceed with actually loading the bean definitions.
        //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 
        initBeanDefinitionReader(beanDefinitionReader);
        //Bean读取器真正实现加载的方法 
        loadBeanDefinitions(beanDefinitionReader);
    }
    

    ...
    
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        //获取配置资源的定位 
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            for (String configLocation : configLocations) {
            //XmlBean读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源  
                reader.loadBeanDefinitions(configLocation);
            }
        }
    }
    
}

第九步:

public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {


//从指定的资源加载bean定义,返回bean定义的数量
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
        ResourceLoader resourceLoader = getResourceLoader();//得到资源加载器
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException(
                    "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
        }

        if (resourceLoader instanceof ResourcePatternResolver) {
            // Resource pattern matching available.
            try {
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                int loadCount = loadBeanDefinitions(resources);//得到加载bean定义的数量,而且在这里将bean定义注入进了spring容器中
                if (actualResources != null) {
                    for (Resource resource : resources) {
                        actualResources.add(resource);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
                }
                return loadCount;
            }
            catch (IOException ex) {
                throw new BeanDefinitionStoreException(
                        "Could not resolve bean definition resource pattern [" + location + "]", ex);
            }
        }
        else {
            // Can only load single resources by absolute URL.
            Resource resource = resourceLoader.getResource(location);
            int loadCount = loadBeanDefinitions(resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }
            return loadCount;
        }
    }

    
    public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
        Assert.notNull(resources, "Resource array must not be null");
        int counter = 0;
        for (Resource resource : resources) {
            counter += loadBeanDefinitions(resource);//加载不同的资源类型,使用不同的具体子类来加载,这里使用的是xml。所以他的子类是XmlBeanDefinitionReader,还有一个子类是PropertiesBeanDefinitionReader
        }
        return counter;
    }
    
}
原文地址:https://www.cnblogs.com/hjy9420/p/4216577.html