探索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。

相关文章
相关标签/搜索