一场雨

spring的IOC容器的初始化

1.BeanFactory

2.初始化的三个过程:Resource的定位,BeanDefinition的载入,向ioc容器注册这些BeanDefinitio。

Resource定位功能:

public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext

FileSystemXmlApplicationContext中都是构造方法。

public abstract class AbstractApplicationContext extends DefaultResourceLoader

关于IOC容器的相关功能的实现,都是在FileSystemXmlApplicationContext中完成的,在构造函数的中的refresh来启动。

//在对象初始化过程中,调用refresh函数载入BeanDefinition。

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

//用于文件系统中的Resource的实现,通过构造一个FileSystemResource来得到一个在文件系统中定位的BeanDefinition
//getResourceByPath在BeanDefinitionReader的LoadBeanDefiniton中调用。

@Override
protected Resource getResourceByPath(String path) {
    if (path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    return new FileSystemResource(path);
}

getResourceByPath生成的是一个FileSystemResource对象,如果是其它的ApplicationContext会生成其它类型的Resource。

createBeanFactory创建了一个IOC容器供ApplicationContext使用,这个容器是DefaultListableBeanFactory,同时,他启动了loadBeanDefinition来载入BeanDefinition.

初始化FileSystmXmlApplicationContext的过程中,通过的方法就是refresh方法,使用的ioc容器是:DefultListableBeaFactory,具体的资源载入:AbstractBeanDefinitionReader中的loadBeanDefinitions实现资源的加载

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean
  definition source for " + getDisplayName(), ex);
    }
}

refresh()方法,AbstractApplicationContext

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {

        prepareRefresh();

  //这边就有refreshBeanFactory的调用
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        prepareBeanFactory(beanFactory);

        try {

            postProcessBeanFactory(beanFactory);

            invokeBeanFactoryPostProcessors(beanFactory);

            registerBeanPostProcessors(beanFactory);

            initMessageSource();

            initApplicationEventMulticaster();

            onRefresh();

            registerListeners();

            finishBeanFactoryInitialization(beanFactory);

            finishRefresh();
        }

        catch (BeansException ex) {
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        }
    }
}

BeanDefinition的载入和解析
载入的过程相当于是把BeanDefinition在IOC容器中转换成一个Spring内部表示的一个数据结构的过程.
载入的重点在于将资源转换成Spring能够认识的结构,相当于文件的解析,xml格式的比较的多。
注意下这个类:DefaultListableBeanFactory

Alt text.

Alt text.

AbstractRefreshableApplicationContext中有一个方法:refreshBeanFactory();来实例化一个BeanFactory的,在创建ioc容器之前,如果已经有容器存在了,就将已有的容器销毁和关闭。
这里的loadBeanDefinitions中,初始化读取器XmlBeanDefinitionReader,然后这个读取器在ioc容器中设置好,最后启动读取器来完成BeanDefinition在ioc容器中的载入。

//AbstractXmlApplicationContext
@Override
protected void loadBeanDefinitions(
DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

经过逐层的解析,我们在XML中定义的BeanDefinition就被整个的载入到了IOC容器中去了,并在容器中建立了数据的映射,至此,IOC容器大致完成了管理Bean对象的数据准备,接着需要完成注册的过程。

BeanDefinition在IOC中的注册

HashMap结构.