码迷,mamicode.com
首页 > 编程语言 > 详细

Spring源码阅读四 IOC

时间:2016-10-15 13:40:23      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

前面讲了 简单的实现方式通过FileSystemXmlApplicationContext这个类来实现,那么今天看下这个类做了什么,是如何完成IOC的?

上代码:

 

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

我们跟踪上一章FileSystemXmlApplicationContext的构造函数,可以发现它最终调用的是上面这个形式重载的构造函数,其中的refresh方法,便是IOC容器初始化的入口。下面我们继续跟踪代码进去看一下refresh方法。refresh方法位于AbstractApplicationContext中,这是一个抽象类,初步实现了ApplicationContext的一般功能,并且这里使用了模板模式,给以后要实现的子类提供了统一的模板。

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

refresh()方法在  AbstractApplicationContext中,是个抽象类。这个方法运用了模板方法模式。

 这里面列出了IOC容器初始化的大致步骤,第一步很容易看出来是初始化准备,这个方法里只是设置了一个活动标识,我们主要来看第二步,obtainFreshBeanFactory这个方法,它是用来告诉子类刷新内部的bean工厂,接下来我们跟踪进去看看。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

该方法中第一句便调用了另外一个refreshBeanFactory方法,这个方法是AbstractApplicationContext中的抽象方法,具体的实现并没有在这个抽象类中实现,而是留给了子类,我们追踪到这个子类当中去看一下。该方法又子类AbstractRefreshableApplicationContext实现,我们来看

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

 

 方法加上了final关键字,也就是说此方法不可被重写,可以很清楚的看到,IOC容器的初始化就是在这个方法里发生的,第一步先是判断有无现有的工厂,有的话便会将其摧毁,否则,就会创建一个默认的bean工厂,也就是前面提到的DefaultListableBeanFactory,注意看loadBeanDefinitions(beanFactory);这里,当我们创建了一个默认的bean工厂以后,便是载入bean的定义。这与我们上一章所使用的原始的创建bean工厂的方式极为相似。

           看到这里,其实不难看出,FileSystemXmlApplicationContext的初始化方法中,其实已经包含了我们上一章当中原始的创建过程,这个类是一个现有的,spring已经为我们实现好的BeanFactory的实现类。在项目当中,我们经常会用到。

Spring源码阅读四 IOC

标签:

原文地址:http://www.cnblogs.com/chenjian98/p/5963089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!