一次ApplicationContext的實例化過程

好記性不如爛筆頭。記一下對ApplicationContext實例化的過程的吧。

代碼:

ApplicationContext context =
        new ClassPathXmlApplicationContext("applicationContext.xml");
首先進入的代碼是:
    static {
        ContextClosedEvent.class.getName();
    }

這個代碼塊在AbstractApplicationContext裏,是ClassPathXmlApplicationContext的父類,所以靜態代碼塊先運行。(所以這句代碼的作用是啥呢?求大佬指導)

進入代碼:
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }

之後調用本類的另一個構造方法

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

    }

 

調用父類AbstractXmlApplicationContext構造方法

調用父類AbstractRefreshableConfigApplicationContext構造方法

調用父類AbstractRefreshableApplicationContext構造方法

調用父類AbstractApplicationContext構造方法

    public AbstractApplicationContext(ApplicationContext parent) {
        this();//調用AbstractApplicationContext的無參構造方法
        this.setParent(parent);
    }
    public AbstractApplicationContext() {
        this.logger = LogFactory.getLog(this.getClass());
        this.id = ObjectUtils.identityToString(this);
//這個應用上下文的ID
        this.displayName = ObjectUtils.identityToString(this);
//這個應用上下文(ApplicationContext)的名稱,由這個類的 類名+ @ + 這個context對象的hash值 組成。
        this.beanFactoryPostProcessors = new ArrayList();
///這個List用於存放Bean工廠處理器(BeanFactoryPostProcessor)
        this.active = new AtomicBoolean();
//當前context是否正處於的活動狀態
        this.closed = new AtomicBoolean();
//當前context是否關閉
        this.startupShutdownMonitor = new Object();
        this.applicationListeners = new LinkedHashSet();
        this.resourcePatternResolver = this.getResourcePatternResolver();
//從 PathMatchingResourcePatternResolver 類上的註釋可知 該類支持 Ant 風格的路徑解析
    }

設置配置文件路徑

public void setConfigLocations(String... locations) {
        if (locations != null) {
            Assert.noNullElements(locations, "Config locations must not be null");
            this.configLocations = new String[locations.length];

            for(int i = 0; i < locations.length; ++i) {
//遍歷路徑數組,將 解析(分解) 後的路徑放到 configLocations 中
                this.configLocations[i] = this.resolvePath(locations[i]).trim();
            }
        } else {
            this.configLocations = null;
        }

    }

調用refresh方法

AbstractApplicationContext的refresh()方法是spring的核心,在其中完成了容器的初始化

 public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
//實例化和註冊beanFactory中擴展了BeanPostProcessor的bean。
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

//這裏得新寫一篇

//以上就是實例化ApplicationContext的過程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章