探索SpringBoot-一塊兒看看Spring核心源碼之ApplicationContext(八)

前文回顧

上篇 探索SpringBoot-一塊兒看看Spring核心源碼之BeanFactory(七)介紹了幾個概念。java

  1. BeanFactory接口定義了Ioc容器最基本的方法。
  2. DefaultListableBeanFactory是實現BeanFactory基本功能的實現類。

ApplicationContext

可是,小夥伴們。咱們通常使用的更可能是ApplicationContext,而不是使用僅僅實現了BeanFactory的實現類。那麼ApplicationContextBeanFactory之間的區別和聯繫是什麼呢?web

/** * Central interface to provide configuration for an application. * This is read-only while the application is running, but may be * reloaded if the implementation supports this. * * <p>An ApplicationContext provides: * <ul> * <li>Bean factory methods for accessing application components. * Inherited from {@link org.springframework.beans.factory.ListableBeanFactory}. * <li>The ability to load file resources in a generic fashion. * Inherited from the {@link org.springframework.core.io.ResourceLoader} interface. * <li>The ability to publish events to registered listeners. * Inherited from the {@link ApplicationEventPublisher} interface. * <li>The ability to resolve messages, supporting internationalization. * Inherited from the {@link MessageSource} interface. * <li>Inheritance from a parent context. Definitions in a descendant context * will always take priority. This means, for example, that a single parent * context can be used by an entire web application, while each servlet has * its own child context that is independent of that of any other servlet. * </ul> * * <p>In addition to standard {@link org.springframework.beans.factory.BeanFactory} * lifecycle capabilities, ApplicationContext implementations detect and invoke * {@link ApplicationContextAware} beans as well as {@link ResourceLoaderAware}, * {@link ApplicationEventPublisherAware} and {@link MessageSourceAware} beans. * 複製代碼

定義是對一個應用提供配置的核心接口。spring

下面又講到了ApplicationContext提供的幾個能力。app

  1. 擁有BeanFactory訪問基本容器組件的能力
  2. 加載文件的能力,繼承了ResourceLoaderResource
  3. 發佈事件到註冊的監聽器的能力,繼承了接口ApplicationEventPublisher
  4. 處理消息,支持國際化的能力,能夠看到繼承了MessageSource接口

看下面的類繼承圖,能夠更加清晰看到不一樣類之間的繼承關係ide

因此,ApplicationContext比BeanFactory擁有更多,更強大的功能。ApplicationContext是一中更加高級的容器。通常在開發應用的過程當中,通常都使用ApplicationContext做爲基本的IoC容器。而後,咱們再來看一下ClassPathXmlApplicationContext的具體實現。函數

ClassPathXmlApplicationContext

廢話很少說,直接上源碼。能夠看到基本上在ClassPathXmlApplicationContext只作了三件事情。post

  1. 寫了一個構造函數ClassPathXmlApplicationContext(String[],Boolean,ApplicationContext),
  2. 寫了另一個構造函數ClassPathXmlApplicationContext(String,Class,ApplicationContext)的構造函數。
  3. 寫了getConfigResources的接口,並且是protected的,估計是設計爲了以後繼承的子類使用的。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {

	private Resource[] configResources;
..................................................................

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

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

	public ClassPathXmlApplicationContext(String path, Class clazz) throws BeansException {
		this(new String[] {path}, clazz);
	}
    ...................................................

	public ClassPathXmlApplicationContext(String[] paths, Class clazz, ApplicationContext parent) throws BeansException {

		super(parent);
		Assert.notNull(paths, "Path array must not be null");
		Assert.notNull(clazz, "Class argument must not be null");
		this.configResources = new Resource[paths.length];
		for (int i = 0; i < paths.length; i++) {
			this.configResources[i] = new ClassPathResource(paths[i], clazz);
		}
		refresh();
	}


	@Override
	protected Resource[] getConfigResources() {
		return this.configResources;
	}

}
複製代碼

因此,其實關於ClassPathXmlApplicationContext類裏面的實現邏輯實際上是很是少並且簡單的。另外,咱們也應該注意到在構造函數中最後都會使用到refresh函數。其實這個refresh過程會牽涉Ioc容器啓動的一系列複雜的過程,並且對於不一樣的容器實現,這個過程都是類似的,由於實在抽象的基類裏面實現的。this

結合咱們在 探索SpringBoot-一塊兒來看看Spring容器加載核心源碼(六)中提到的refresh源代碼,咱們能夠看到該函數大體會有如下三個步驟。spa

  1. BeanDefinition的Resource定位
  2. 載入
  3. 註冊

《Spring技術內幕》中也提到了設計

Spring把這三個過程分開,並使用不一樣的模塊來完成,如使用想要的ResourceLoader、BeanDefinitionReader等模塊,經過這樣的設計方式,可讓用戶更加靈活地對三個過程進行剪裁或擴展,定義出最適合本身的IoC容器的初始化過程。

下篇逐個分析初始化的三個過程。

關於

之後這裏天天都會寫一篇文章,題材不限,內容不限,字數不限。儘可能把本身天天的思考都放入其中。

若是這篇文章給你帶來了幫助,能請你寫下是哪一個部分嗎?有效的反饋是對我最大的幫助。

我是shane。今天是2019年8月13日。百天寫做計劃的第二十天,20/100。

相關文章
相關標籤/搜索