首页 > 代码库 > spring容器启动的加载过程(二)

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;    }    }

 

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