IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring ioc容器源码解读 -> 正文阅读

[Java知识库]spring ioc容器源码解读

Spring是每个java程序员都必须要掌握的技能,很多人都想通过阅读源码来提升自己的技术深度,这里分享一下我读源码的方法。

我觉得看源码应该先大概的读,知道主脉络,然后再去读细节,这样才不会乱,先放上我画的图(不怎么会画,大概看看就好,最大的正方形就是ioc容器)
在这里插入图片描述
然后我们来看一下照着图来走一下代码

在springboot启动类打断点
public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

经过SpringApplication构造函数完成一些初始化操作后来到
SringApplication这个类的ConfigurableApplicationContext 方法,
这个方法我们主要看 this.refreshContext(context); 这一行,这是创建ioc容器的方法,其他的可以等熟悉了主要脉络再去细看

public ConfigurableApplicationContext run(String... args) {
		//计时器实例,并设置计时器id,name和开始时间
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		//系统属性设置 一般是在程序开始激活headless模式,告诉程序,现在你要工作在Headless mode下,就不要指望硬件帮忙了,你得自力更生,依靠系统的计算能力模拟出这些特性来
		configureHeadlessProperty();
		//初始化监听器   META-INF/spring.factories文件中获取SpringApplicationRunListener接口的实现类。
		SpringApplicationRunListeners listeners = getRunListeners(args);
		//启动已经准备好的监听器  getSpringFactoriesInstances
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
			//装配环境参数  保存args参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			// 准备环境变量, 读取 bootstrapContext application.properties文件中的环境变量
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			// 系统配置忽略标志spring.beaninfo.ignore
			configureIgnoreBeanInfo(environment);
			//打印banner图案
			Banner printedBanner = printBanner(environment);
			//创建ConfigurableApplicationContext(应用配置上下文)
			context = createApplicationContext();
			context.setApplicationStartup(this.applicationStartup);
			//将listeners、environment、applicationArguments、banner等重要组件与上下文对象关联
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			//这个方法很重要 ioc容器的创建
			refreshContext(context);
			//ioc容器创建后
			afterRefresh(context, applicationArguments);
			//计时结束
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

一路进去AbstractApplicationContext这个实现类的refresh()方法

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            //初始化工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
            this.prepareRefresh();
            //这个是创建bean工厂的方法主要是createBeanFactory():创建BeanFactory和loadBeanDefinitions() :加载BeanDefinination两个方法
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //填充beanFactory属性
            this.prepareBeanFactory(beanFactory);

            try {
            //这是一个扩展点
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
              //实例化并调用所有注册的BeanFactoryPostProcessors
              this.invokeBeanFactoryPostProcessors(beanFactory);
              // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                //国际化相关
                this.initMessageSource();
                // 初始化当前 ApplicationContext 的事件广播器
                this.initApplicationEventMulticaster();
                // 从方法名就可以知道,典型的模板方法(钩子方法),
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
                this.onRefresh();
                // 注册事件监听器,监听器需要实现 ApplicationListener 接口
                this.registerListeners();
                // 重点,重点,重点
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         this.finishBeanFactoryInitialization(beanFactory);
         // 最后,广播事件,ApplicationContext 初始化完成
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }
				// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
                this.destroyBeans();
                // Reset 'active' flag.
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

        }
    }

对于上面大家不知道BeanFactoryPostProcessor和BeanPostProcessor是干嘛的。大家可以看看这篇文章

https://blog.csdn.net/caihaijiang/article/details/35552859

然后这里给大家说一下具体每个方法做了什么

  1. prepareRefresh
	protected void prepareRefresh() {
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		// ①在上下文环境中初始化任何占位符属性源。
		initPropertySources();

		// ②验证所有标记为required的属性都是可解析的:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

ApplicationContext刷新前的准备工作,比如设置启动时间(startupDate),激活标志(active & closed),以及执行属性源的初始化(见阐释)
阐释:
①initPropertySources()是模板抽象方法,用户可以根据需要进行重写。 Warn见WebApplicationContext解析

	protected void initPropertySources() {
		// For subclasses: do nothing by default.
	}
  

我们可以覆盖该方法,进行自定义的属性处理以及设置。比如如果项目的启动必须依赖于当前机器的环境变量ENV,那么我们可以这样写:

	protected void initPropertySources() {
		// For subclasses: do nothing by default.
		getEnvironment().setRequiredProperties("ENV")
	}

②getEnvironment().validateRequiredProperties(),对所有被标记为required的属性进行验证

在前面我们知道,这里的envirmonent是一个StandardEnvironment,它是ConfigurablePropertyResolver的子类,故而它可以执行validateRequiredProperties()方法(因为该方法是由ConfigurablePropertyResolver接口声明的)。

我们还知道AbstractEnvironment中声明了一个类型为ConfigurablePropertyResolver的propertyResolver属性,并硬编码其值为PropertySourcesPropertyResolver对象。在这里的验证required属性的工作也是交给了这个PropertyResolver来处理!!

具体的验证逻辑读者可以自行阅读源码,其实:

  • setRequiredProperties()是将字符串加入到一个由AbstractPropertyResolver维护的一个名为requiredProperties的Set集合中
  • validateRequiredProperties()仅仅是循环requiredProperties并验证存在罢了。
	private final ConfigurablePropertyResolver propertyResolver =
			new PropertySourcesPropertyResolver(this.propertySources);
	@Override
	public void validateRequiredProperties() throws MissingRequiredPropertiesException {
		this.propertyResolver.validateRequiredProperties();
	}
  1. obtainFreshBeanFactory
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}
	protected final void refreshBeanFactory() throws BeansException {
	    //如果当前存在beanFactory,则先销毁掉
		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);
		}
	}
}

概述:refreshBeanFactory()方法对ApplicationContext上下文的底层beanFactory执行真正的刷新,先关闭之前的beanFactory(如果有的话),并为当前的ApplicationContext上下文生命周期的下一阶段初始化一个新的beanFactory。

refreshBeanFactory()方法中的核心方法调用分别是:

  • createBeanFactory():创建BeanFactory
  • loadBeanDefinitions() :加载BeanDefinination

createBeanFactory

	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}

下面是DefaultListableBeanFactory的创建历程
在这里插入图片描述
该过程仅仅是BeanFactory的实例化,并设置一些比较公共的配置,不予讲解,感兴趣的可以自己Debug看看

loadBeanDefinitions

	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 为给定的BeanFactory创建一个XmlBeanDefinitionReader
		// XmlBeanDefinitionReader用于读取XML并解析为BeanDefinition,并进行注册
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 为BeanDefinition的读取器,配置资源加载器,环境变量,以及EntityResolver(用于判断)
		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);
	}

Ⅰ.首先,使用给定的BeanFactory类型的入参,创建一个XmlBeanDefinitionReader

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
	//提供了对Document的解析能力,并将解析后的BeanDefinition注册到BeanDefintionRegistry对象上
	private Class<? extends BeanDefinitionDocumentReader> documentReaderClass =
			DefaultBeanDefinitionDocumentReader.class;
	@Nullable
	//处理自定义标签时候需要使用,它可以访问我们注册的自定义标签解析器,完成对自定义标签的解析
	//默认的实现是DefaultNamespaceHandlerResolver
	private NamespaceHandlerResolver namespaceHandlerResolver;
	//将Resource转为Document的加载器,纯技术SAX技术,无需关心
	private DocumentLoader documentLoader = new DefaultDocumentLoader();
	@Nullable
	private EntityResolver entityResolver;
	private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded =
			new NamedThreadLocal<>("XML bean definition resources currently being loaded");
	public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
		//直接调用方父类构造器
		super(registry);
	}
}
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
    //用于注册解析的BeanDefinition(说白了,就是将解析出的BeanDefinition,放到registry里保存,以用于bean实例化)
	private final BeanDefinitionRegistry registry;
	@Nullable
	//用于加载配置文件的处理器,它可以将配置及文件解析为Resourced对象,以用于后面将Resource通过SAX转为Document对象
	private ResourceLoader resourceLoader;
	@Nullable
	//ApplicationContext的类加载器
	private ClassLoader beanClassLoader;
	//环境变量
	private Environment environment;
	//XmlBeanDefinitionReader的父类AbstractBeanDefinitionReader
	protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;
		// 根据传入的registry,决定ResourceLoader(它是用于加载配置文件的加载器)
		if (this.registry instanceof ResourceLoader) {
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}
		// 如果可能的话,继承Environment
		if (this.registry instanceof EnvironmentCapable) {
			this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
		}
		else {
			this.environment = new StandardEnvironment();
		}
	}

}

注:从XmlBeanDefinitionReader的构造器参数签名中,我们发现其实XmlBeanDefinitionReader需要的是一个BeanDefinitionRegistry对象,但是因为我们刚才生成的BeanFactory实现了该接口,故而可以作为入参。

阐释:真实的构造逻辑在AbstractBeanDefinitionReader中实现的,它将我们传入的registry,赋值给自己的registry属性上

验证传入的这个registry(本例中指的是beanFactory)是否是一个ResourceLoader接口的实现:

  • 如果是:直接将该其赋值给resourceLoader属性
  • 如果否:创建一个PathMatchingResourcePatternResolver对象,然后赋值给resourceLoader属性。本例中的beanFactory是DefaultListableBeanFactory,它并没有实现ResourceLoader。PathMatchingResourcePatternResolver是对DefaultResourceLoader(它是ResourceLoader的默认实现)的二次封装,它额外添加了对classpath*:
    或者 war: 或者 */ 等路径语法的支持!!!

然后验证传入的这个registry(即该beanFactory)是否是一个EnvironmentCapable接口的实现:

  • 如果是:则将其赋值给environment属性
  • 如果否:则创建一个StandardEnvironment并赋值给environment属性

PS:ResourceLoader是用于加载资源文件为Resource对象的,故而对XmlBeanDefinitionReader很重要

Ⅱ. 实例化完XmlBeanDefinitionReader,对其进行配置

		// 使用该上下文的资源加载环境,来配置XmlBeanDefinitionReader
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		//请注意,这里对ResourceLoader进行了重新赋值,即将this,即ClassPathXmlApplicationContext赋值给它
		//ClassPathXmlApplicationContext的父类继承自DefaultResourceLoader(它是ResourceLoader的默认实现),因此它是一个有效的ResourceLoader
		//多嘴一句,ClassPathXmlApplicationContext并不是直接复用DefaultResourceLoader,而是在其内部初始化了一个PathMatchingResourcePatternResolver类型的resourcePatternResolver变量,在真正加载文件时,全权交给他,如果是模式匹配的,那么它就处理了,如果并模式匹配,那么再复用这个DefaultResourceLoader。
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 允许子类提供Reader的自定义初始化(保留给子类使用的)
		initBeanDefinitionReader(beanDefinitionReader);

Ⅲ .loadBeanDefinitions(beanDefinitionReader)

	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

概述:对ApplicationConext的configLoacations进行for循环,分别交给XmlBeanDefinitionReader单解析
阐述:需要注意的是,我们在最前面讲了,ApplicationContext将配置文件的路径,存储在configLocations属性中。因此在解析BeanDefinition之前,需要先将该配置文件提取出来,然后交给XmlBeanDefinitionReader去操作(因为XmlBeanDefinitionReader与ApplicationmContext并没有直接关系,因此无法在运行时获取到这些配置文件的信息)。

public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
	public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");
		int count = 0;
		for (String location : locations) {
			count += loadBeanDefinitions(location);
		}
		return count;
	}
	@Override
	public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}
	public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
	    //还记得为XmlBeanDefinitionReader单独配置的ResourceLoader吗??
	    //这里需要使用它,将configLocation里的配置文件路径,加载解析为Resource资源
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
		}
		if (resourceLoader instanceof ResourcePatternResolver) {
			// 资源的模式匹配功能可用.本例子中的resourceLoader是ClassPathXmlApplicationContext,它所实现的ResolveLoader是具有资源模式匹配的能力的
			try {
			    //将资源加载的工作委托给resourceLoader
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int count = loadBeanDefinitions(resources);
				if (actualResources != null) {
					Collections.addAll(actualResources, resources);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
				}
				return count;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// 资源的模式匹配功能不可用,只可以通过绝对URL加载单一资源
			Resource resource = resourceLoader.getResource(location);
			int count = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
			}
			return count;
		}
	}
}

注:XmlBeanDefinitionReader是AbstractBeanDefinitionReader的子类
配置文件资源的加载比较简单,看上面的注释即可,接下来着重讲解loadBeanDefinitions方法调用

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
	@Override
	//对Resource进行编码
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);
		}
		//resourcesCurrentlyBeingLoaded中存储了当前正在被解析的Resource的Set集合,防止同一Resource被多次解析
		//文件被解析完后,会从Set集合中删除掉
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
		    //获取编码后的Resource的文件流
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
			    //使用InputSourece对InputStream进行封装(因为SAX值只识别IputSouce)
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//BeanDefinition加载
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}
	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
		    //使用XmlBeanDefinitionReader的类型为DefaultDocumentLoader的documentLoader变量,来将Resource解析为Document
		    //纯SAX技术,无需care
			Document doc = doLoadDocument(inputSource, resource);
			//
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
	}
	//提供了对Document的解析能力,并将解析后的BeanDefinition注册到BeanDefintionRegistry对象上
	private Class<? extends BeanDefinitionDocumentReader> documentReaderClass =
			DefaultBeanDefinitionDocumentReader.class;
	@Nullable
	//处理自定义标签时候需要使用,它可以访问我们注册的自定义标签解析器,完成对自定义标签的解析
	//默认的实现是DefaultNamespaceHandlerResolver
	private NamespaceHandlerResolver namespaceHandlerResolver;
	//将Resource转为Document的加载器,纯技术SAX技术,无需关心
	private DocumentLoader documentLoader = new DefaultDocumentLoader();
	@Nullable
	private EntityResolver entityResolver;
	
	protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
		return BeanUtils.instantiateClass(this.documentReaderClass);
	}
	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	    //创建一个可以解析Doument的解析器
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		int countBefore = getRegistry().getBeanDefinitionCount();
		//使用documentReader完成BeanDefinition的提取,构造和注册(注册到BeanDefinitionRegistry上)
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}
}

这一块代码体量较大,但是工作内容很简单,读者可以参考我的注释,脑海里勾勒粗Spring的处理过程,为了简答起见,我以直白的表述,阐释这个过程.:

在前面,我们通过XmlBeanDefinitionReader中的ResourceLoader,将配置文件解析为Resource,我们先对该Resource做编码(比如UTF-8等格式的编码),然后提取该资源的InputStream,最终将其转换为可以为SAX解析器所识别的InputSource对象。

XmlBeanDefinitionReader中定义了一个类型为DefaultDocumentLoader的documentLoader变量,通过该加载器,可以将InputSource解析为Document对象。

XmlBeanDefinitionReader还定义了一个专门负责解析Document的读取器,即DefaultBeanDefinitionDocumentReader,我们将前面DocumentLoader解析生成的Document对象交付给它,并附带一个XmlReaderContext对象。

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
	//创建一个XmlReaderContext,即Xml配置文件读取的上下文,用于承载一些读取、解析Xml配置文件时
	//所需要使用的一些工具处理器,比如配置文件的Resource、NamespaceHandlerResolver等
	public XmlReaderContext createReaderContext(Resource resource) {
		return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
				this.sourceExtractor, this, getNamespaceHandlerResolver());
	}
	public NamespaceHandlerResolver getNamespaceHandlerResolver() {
		if (this.namespaceHandlerResolver == null) {
			//初始化XmlBeanDefinitionReader时并未设置namespaceHandlerResolver属性,因此
			//会创建一个NamespaceHandlerResolver的默认实现类:DefaultNamespaceHandlerResolver的实例
			this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
		}
		return this.namespaceHandlerResolver;
	}
}

注:XmlReaderContext,是Per-Resource的,即一个Resource对应一个Document,而每个Docunent则对用唯一的专用ReaderContext对象。该对象提供了对NamespaceHandlerResolver的访问,使用的是DefaultNamespaceHandlerResolver这个默认实现,当然,这是XmlBeanDefinitionReader在构造它时,为其装载的)。

具体的BeanDefinition解析逻辑,完全的委托给了DefaultBeanDefinitionDocumentReader,注目观看:

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}
	protected void doRegisterBeanDefinitions(Element root) {
	    //入参是Document的根元素
	    //DefaultBeanDefinitionDocumentReader将Element元素的解析工作,委托给了BeanDefinitionParserDelegate来负责
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
		//profile验证
		if (this.delegate.isDefaultNamespace(root)) {
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}
		//模板方法,实现是空的,由用户自定义,在真正处理XML解析之前做什么...
		preProcessXml(root);
		//BeanDefinition核心解析方法
		parseBeanDefinitions(root, this.delegate);
		//模板方法,实现是空的,由用户自定义,在真正处理XML解析之前做什么...
		postProcessXml(root);
		this.delegate = parent;
	}
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//注意:这里的元素是根节点Element
		//如果delegate判断该Element是属于默认命名空间的,那么取出子节点,循环解析
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					//如果子节点是默认命名空间的元素
					if (delegate.isDefaultNamespace(ele)) {
						//解析默认元素的方法
						parseDefaultElement(ele, delegate);
					}
					else {
						//如果是自定义命名空间的元素,则调用解析自定义元素的方法
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			//如果根元素就是自定义明明空间的元素,则调用解析自定义元素的方法
			delegate.parseCustomElement(root);
		}
	}
	protected BeanDefinitionParserDelegate createDelegate(
			XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) {

		BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
		delegate.initDefaults(root, parentDelegate);
		return delegate;
	}

}

概述:DefaultBeanDefinitionDocumentReader将Element解析的重任,委托给了BeanDefinitionParserDelegate对象,而它则负责Document中Element的拆解,元素识别以及调用delegate的适当方法做元素的解析,最终生成BeanDefinition对象。

阐释:DefaultBeanDefinitionDocumentReader在这里的作用,更像是一个装备工人,它购买一个BeanDefinitionParserDelegate机器(该机器可以将Element解析为一个BeanDefinition),然后使用它判断原料(即Document的根元素)是否是Spring原厂(即Spring默认命名空间)的:

  • 如果该Element是原厂的,那说明是使用Spring的标准配置的配置文件,那么先拆解该根元素,取出所有的子元素,for迭代,然后在交给BeanDefinitionParserDelegate来判断该子元素是否是Spring原厂的(比如Spring所支持的<
    bean />
    元素),如果是原厂支持的,那么调用parseDefaultElement(element,delegate)做二次解析,毕竟各种元素的处理方法是不一样的,比如<
    bean />,以及< import
    />等。如果子元素并非Spring原厂支持的,亦即自定义的,那么完全委托给BeanDefinitionParserDelegate的parseCustomElement()方法去处理
  • 如果子元素并非原厂的,那么完全委托给BeanDefinitionParserDelegate的parseCustomElement()方法去处理

先看如何加工Spring原厂的Element:

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			//如果该子元素是<import>,那么先对import内文件地址解析,即替换掉${...},然后进行beanDefinition的解析工作,这个过程与我们传给ClassPathXmlApplicationContext的配置文件的解析过程一毛一样,也建议读者自行阅读源码
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			//如果该子元素是<alias>,那么直接在readerContext中的registry上注册该别名即可
			//实现比较简单,建议读者自行阅读源码
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			//如果盖子元素是一个<bean>,那么完全委托给deleaget去解析
			processBeanDefinition(ele, delegate);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// 如果该子元素是一个<beans>,那么递归调用doRegisterBeanDefinitions
			doRegisterBeanDefinitions(ele);
		}
	}
}

概述:方法很简单,根据Element的节点名称,调用不同的方法去解析及注册

最重要的就是< bean />元素的处理,下面着重描述:

	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		//委托给delegate全权处理element的解析,返回一个BeanDefinitionHolder
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			//若可以,对BeanDefinitionHolder进行包装,也是很重要的
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 将最终包装过的BeanDefinitionHolder,注册到BeanDefinitionRegistry上
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// 发送注册消息
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

最重要的三个步骤:

  • delegate.parseBeanDefinitionElement(ele);
  • elegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
  • BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,
    getReaderContext().getRegistry());
public class BeanDefinitionParserDelegate {
	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		//提取element的id、name 属性,需要提到的一点是,name属性也被成为别名,name是支持多值得,格式类似于name="piemon,anokata"
		String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<>();
		//将name属性按照分隔符分割开来,并添加到alias列表中
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}
		//将id赋值给beanName,校验:beanNaame不能为空与alias为空不可同时存在
		String beanName = id;
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isTraceEnabled()) {
				logger.trace("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}
		//beanName唯一性校验,前面说过,BeanDefinitionParserDelegate是一个有状态的对象,
		//它使用一个Set<String>类型的usedNames,其中保存beanName和别名(别名也参与一致性校验)
		//实现个很简单,Set中查找beanName,查到就不满足唯一性,异常!否则通过
		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}
		//解析Element元素,生成一个ASbstractBeanDefinition对象(其实真实类型是GenericBeanDefinition,它是AbstractBeanDefinition的子类)
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						beanName = this.readerContext.generateBeanName(beanDefinition);
						// Register an alias for the plain bean class name, if still possible,
						// if the generator returned the class name plus a suffix.
						// This is expected for Spring 1.2/2.0 backwards compatibility.
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isTraceEnabled()) {
						logger.trace("Neither XML 'id' nor 'name' specified - " +
								"using generated bean name [" + beanName + "]");
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			//BeanDefinitionHolder包装BeanDefinition
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}
		//该方法存在无法解析Element的情况,因此返回null
		return null;
	}

	public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {
		//parseState中保存当前正在被解析的beanName,它是一个栈结构,push/pop
		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		//判断<bean>中是否有class属性,如 <bean class="">
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		String parent = null;
		//判断<bean>中是否有parent属性 <bean parent="">
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
			//根据className和parent属性的值,构建AbstractBeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
			//解析<bean>中的attribute
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//给BeanDefinition设置一个用于展示的好看的名字,没啥鸟用
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
			//解析<bean>中的<meta>子标签,也被成为元属性
			parseMetaElements(ele, bd);
			//这两两个解析比较重要,分别下列两种子元素:
			//   <lookup-method name="createCommand" bean="myCommand"/>
			//   <replaced-method name="computeValue" replacer="replacementComputeValue" />
			//这两个特别有用,用于方法注入,并非setter注入哟~~
			//典型场景:Singleton Bean种使用短周期的Bean(比如Proto/Request/Session等Scope的Bean)
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
			//解析构造器参数,即<bean>中的<construct-arg>子元素
			parseConstructorArgElements(ele, bd);
			//解析<bean>中的<property name="" value="">
			parsePropertyElements(ele, bd);
			//<bean class="example.SimpleMovieCatalog">
        <	//	<qualifier value="main"/> 
    		//</bean> 多用于同类型多Bean的情况
			parseQualifierElements(ele, bd);
			//为BeanDefinition设置Resource,就是此Element所存在于的配置文件的Resource表现形式
			bd.setResource(this.readerContext.getResource());
			//功能主要是由SourceExtractor负责的,但是我也不知道干嘛的~~希望读者有懂得,下面留言指点下
			bd.setSource(extractSource(ele));

			return bd;
		}
		catch (ClassNotFoundException ex) {
			error("Bean class [" + className + "] not found", ele, ex);
		}
		catch (NoClassDefFoundError err) {
			error("Class that bean class [" + className + "] depends on not found", ele, err);
		}
		catch (Throwable ex) {
			error("Unexpected failure during bean definition parsing", ele, ex);
		}
		finally {
			//弹出压入得beanName,表示已经解析完成
			this.parseState.pop();
		}

		return null;
	}
	//new一个BeanDefinition
	protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
			throws ClassNotFoundException {
		//将创建BeanDefinition的任务,交给了BeanDefinitionReaderUtils,并设置其parent属性以及beanClassName属性,这些属性都是参数传来的!
		return BeanDefinitionReaderUtils.createBeanDefinition(
				parentName, className, this.readerContext.getBeanClassLoader());
	}
}

概述:BeanDefinitionParserDelegate是一个有状态的委托类,用于解析XML格式的配置文件。parseBeanDefinitionElement(…)方法的作用,是将一个Element,解析成一个BeanDefinition,然后用BeanDefinitionHolder包装一下。
阐述:看注释,更清楚

继续回到Spring原厂元素的解析上,将Element解析为BeanDefinition后,可能还需要包装它,下面讲decorateBeanDefinitionIfRequired:
PS:先看完下面的自定义元素解析(parseCustomerElement),再回头看这里的包装,否则本末倒置了!!!

public class BeanDefinitionParserDelegate {
	public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) {
		//交给重载的方法处理
		return decorateBeanDefinitionIfRequired(ele, originalDef, null);
	}
	public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
			Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {

		BeanDefinitionHolder finalDefinition = originalDef;

		// 首先根据自定义的attribute,进行包装
		NamedNodeMap attributes = ele.getAttributes();
		for (int i = 0; i < attributes.getLength(); i++) {
			Node node = attributes.item(i);
			finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
		}

		// 然后根据内嵌的自定义子元素,进行包装
		// 需要交代一下,我们前面讲过,自定义的元素会交给ddelegate的parseCustomerElemenmt方法解析
		NodeList children = ele.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node node = children.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
			}
		}
		return finalDefinition;
	}
	public BeanDefinitionHolder decorateIfRequired(
			Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
		//首先获取元素的命名空间
		String namespaceUri = getNamespaceURI(node);
		//判断是否是默认的命名空间,Spring的默认命名空进是beans,其他的都不是
		if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
			//如果是自定义的元素,那么很可能会需要包装,我们首先解析出该命名空间的NamespaceHandler
			//该NamespaceHandler的具体类型的父类型是一个NamespaceHandlerSupport,它是NamespaceHandler子类
			NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
			if (handler != null) {
				//每个命名空间都有一个自己的专属NamespaceHandler,当然这是规范,可以不遵守的
				//每个NamespaceHandler里都维护着BeanDefinitionParser的Map:parsers和BeanDefinitionDecorator的map:decorators、map:attributeDecorators(不知道怎么解释,直白一点,前者包装<aop:scope-proxy>,即元素级的包装标签,后者包装的是Attribute级的属性),
				//顾名思义,BeanDefinitionParser是用来解析自定义的元素为BeanDefinition的,
				//而BeanDefinitionDecorator则用来包装
				BeanDefinitionHolder decorated =
						handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
				if (decorated != null) {
					return decorated;
				}
			}
			else if (namespaceUri.startsWith("http://www.springframework.org/")) {
				error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
			}
			else {
				// A custom namespace, not to be handled by Spring - maybe "xml:...".
				if (logger.isDebugEnabled()) {
					logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
				}
			}
		}
		return originalDef;
	}
}

概述:根据Element的命名空间,找到注册的NamespaceHandlerSupport(他是NamespaceHandler接口的子类),然后找出其上注册的BeanDefinitionDecorator,用于对BeanDefinition进行包装。

BeanDefinition的注册:

public abstract class BeanDefinitionReaderUtils {
	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		//首先在beanName下注册BeanDefinition
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 然后注册别名
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
}

概述:该工具方法先在beanName之下注册BeanDefinition,然后在想registry注册其别名吗,使得对别名的引用亦可以指向所属的Bean
阐释:BeanDefinitionRegistry是一个接口,具体的实现是在DefaultListableBeanFactory中实现。

DefaultListableBeanFactory中声明了一堆的Map,因为他实现了BenaDefinitionRegistry接口,所以他需要具有BeanDefinition的注册能力,而下面这些Map就是做这个注册的:

  • beanDefinitionMap:Map<String, BeanDefinition>类型,存储BeanDefinition
  • beanDefinitionNames:List<String,>类型,存储beanName
  • frozenBeanDefinitionNames:String[]类型,冻结的beanName数组
  • aliasMap:Map<String, String>类型,存储别名与beanName的映射
    其实可以将BeanDefinitionRegistry,看做是一个内存数据库,所有的BeanDefinition信息都会记录在其中,用于Bean实例化。
    至此,解析并注册了BeanDefinition~~

parseCustomerElement
Spring默认的命名空间仅包括beans.xsd所支持的配置项,而像aop、tx、context等命名空间,是属于自定义的!!!
在我们的配置项中,添加了对于< context annotation-config >,在< bean />中添加了< aop:scoped-proxy/>,这都是自定义的,为此我们着重解释一下

public class BeanDefinitionParserDelegate {
	public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
		String namespaceUri = getNamespaceURI(ele);
		if (namespaceUri == null) {
			return null;
		}
		//有了Element所归属的命名空间(更直白一点,就是我们知道<context annotation-config>是由哪个命名空间定义的)
		//我们就是提取出readerContext(就是XMLReaderContext,我们在上面讲过),然后用readerContext中的mamespaceHandlerResolver
		//来对这个命名空间URI进行解析,找出该命名空间的处理器,即NamespaceHandler。
		//此处得到NamespaceHandlerResolver是DefaultNamespaceHandlerResolver类型的,它内部维护这一个handlerMapping,
		//Map<String, Object> handlerMappings;,键是命名空间URI,而值则是NamespaceHander或者是class全类名字符串(可以反射生成处理器对象)
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		//将Element交给该NamespaceHandler解析处理
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}
	public String getNamespaceURI(Node node) {
		//Element是Node的子类,Node中声明了getNamespaceURI()方法,获取当前节点的命名空间URI
		//对于<context:annotation-config>,他的命名空间URI就是http://www.springframework.org/schema/context,细心的读者会发现,这是我们在XML上引入的
		return node.getNamespaceURI();
	}
}

获取命名空间URI,然后使用NamespaceHandlerResolver对象,根据命名空间URI,检出对应的命名空间处理器(NamespaceHandelr),最后将Element委托给该handler解析。
注:NamespaceHandler还要负责注册解析的BeanDefinition到BeanDefinitionRegistry上

自定义命名空间比较重要,我先解释一下命名空间、命名空间处理器(NamespaceHandelr)、命名空间URI,不要略过,很简单的:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
</beans>

1.命名空间:xmlns,就是xml命名空间,全称xml-namespace,对于xmlns:context,他对应的命名空间就是“http://www.springframework.org/schema/context”,但是这个名字太长了,我们就给他一个短小精悍的别名,即context,官方的解释是,给命名空间提供一个独一无二的名字。
2.命名空间URI:其实亦可以称其为命名空间,我么可以看一下spring-context.xsd定义(Ctrl就能点进去):

<xsd:schema xmlns="http://www.springframework.org/schema/context"
		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		xmlns:beans="http://www.springframework.org/schema/beans"
		xmlns:tool="http://www.springframework.org/schema/tool"
		##这就是我们context的命名空间
		targetNamespace="http://www.springframework.org/schema/context" 
		elementFormDefault="qualified"
		attributeFormDefault="unqualified">
</xsd:schema>

3.NamespaceHandler:xsd中定义了规范,但是规范没法将这一个个的Element解析成BeanDefinition,这就需要NamespaceHandler登场了,NamespaceHandlerResolver根据命名空间URI,找出其对应的NamespaceHandler,然后让它去帮我们将Element解析成BeanDefinition

下面我就以spring-context来举个栗子!!!
众所周知,< context annotation-config>使得注解变得可能,那么它是如何实现的呢??我们一步步的看:

  1. 首先是spring-context.xsd,他定义了context命名空间的配置规范,使得我们可以在配置文件中使用< context annotation-config> < context conponent-scan> < context load-time-weaver>等等。spring-context.xsd只是一个配置规范,用于限制用户,大家完全可以把它类比成API接口,公共出服务协议。
  2. 我们最终的目标,是需要解析这些XML配置中的Element,而解析的任务,则是由BeanDefinitionParser接口定义的,Spring的Coder自定义一个AnnotationConfigBeanDefinitionParser类,实现BeanDefinitionParser接口,并在其中添加了对Element的解析逻辑
public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
	@Override
	@Nullable
	/**
	* parse方法解析Element,并将解析后的BeanDefinition,通过parserContext.getRegistry()返回的
	* BeanDefinitionRegistry进行注册。
	* 如果解析后的BanDefinition需要以内嵌的形式被使用,比如被ref属性引用,那么返回必须不能为null
	* 如果解析后的BeanDefinition并不需要以内嵌的形式被使用,那么可以返回null
	* 
	* 不得不提的一点是,parserContext是解析上下文,可以与XML配置文件读取的XmlReaderContext类比,parserContext引用了readerContext,而readerContext引用了beanfactory(beanFacory可以注册BeanDefinition,因为他实现了BeanDefinitionRegistry)
	* 和environment(他提供了环境变量和${..}解析)。
	*/
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		Object source = parserContext.extractSource(element);
		// 获取与该注解相关的BeanPostProcessor的beanDefinition
		Set<BeanDefinitionHolder> processorDefinitions =
				AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
		// 为<context:annotation-config> 创建一个CompositeComponentDefinition对象来表示
		CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
		parserContext.pushContainingComponent(compDefinition);

		// 将上面得到的BeanPostProcessor集合,定义为BeanComponentDefinition,并作为该标签的CompositeComponentDefinition的内嵌属性组件,等于声明了一个组件层级关系
		for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
			parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
		}
		parserContext.popAndRegisterContainingComponent();
		//因为该注解是属于配置型的,并没有Bean会依赖它,所以返回null
		return null;
	}

}

public abstract class AnnotationConfigUtils {

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		/**
		* 向BeanDefinitionRegistry注册了一堆BeanPostProcessor和BeanFactoryPostProcessor,
		* 当然并不是通过调用registerBeanPostProcessor来注册,而是注册为BeanDefinition,这样就成为了配置型的BeanPostProcessor
		* 需要提醒的一点是,Spring将beanPostProcessor/beanFactoryPostFactory分成了两类,
		* 一类是硬编码注册的,即通过ApplicationContext的addBeanPostProcessor/addBeanFactoryPostFactory,
		* 第二类则是通过配置配置的,即将BeanPostProcess/BeanFactoryPostProcess注册为BeanDefinition
		* 硬编码的优先级,大于任何配置方式的!!!
		*/
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		//注册一个beanName = internalConfigurationAnnotationProcessor的BeanDefinition
		//他的原始类型是ConfigurationClassPostProcessor类
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}
	
	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}
}

  1. NamespaceHandelr:AnnotationConfigBeanDefinitionParser更像是建筑工人,而NamespaceHandler则是包工头。
//一步了然
//当遇见context命名空间中的annotation-config时候,使用AnnotationConfigBeanDefinitionParser来解析
//当遇到context命名空间中的component-scan时候,使用ComponentScanBeanDefinitionParser来解析
public class ContextNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}

  1. 注册NamespaceHandler,META-INF文件夹下,编写spring.handlers和spring.schemas文件
    spring.handelrs
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler

spring.schemas

http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang.xsd
http\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task.xsd
http\://www.springframework.org/schema/cache/spring-cache.xsd=org/springframework/cache/config/spring-cache.xsd
//
https\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context.xsd
https\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee.xsd
https\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang.xsd
https\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task.xsd
https\://www.springframework.org/schema/cache/spring-cache.xsd=org/springframework/cache/config/spring-cache.xsd

Spring遇到自定义的命名空间,比如context,他会首先解析出他的NamespaceURI,也就是http://www.springframework.org/schema/context,然后让NamespaceHandlerResolver去查找该命名空间的NamespaceHandler,他去查找spring.handlers文件,就可以找到ContextNamespaceHandler,继而可以找到annotation-config的BeanDefinitionParser:AnnotationConfigBeanDefinitionParser

  1. 使用,有了这些基础工作,我们就可以在XML中使用context上下文:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:contexts="http://www.springframework.org/schema/context" ##为该命名空间起一个别名contexts(注意,我们没有用context,这个名字可以随意改变)
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context					##contexts命名空间的schema地址
        http://www.springframework.org/schema/context/spring-context.xsd">
</beans>       

自定义的Element也解析完毕,听懂了吗??

prepareBeanFactory

填充BeanFactory属性

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 告知BeanFactory使用与ApplicationContext一样的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		//配置SPEL表达式的支持,即#{beanName.field}用法
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//配置属性编辑器,我们为什么可以在配置Bean的时候,用字符串表达数值等的意思??因为PropertyEditor帮我们转换了
		//<property name="age" value="99">  这里的99是个int,但是我们依然可以用字符串配置它
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		/**
		* 配置BeanPostProcessor,BeanPostProcessor会在实例化Bean的init-method方法之前前后分别
		* 调用其postProcessBeforeInitialization和postProcessAfterInitialization方法
		* 我们可以深入看下ApplicationContextAwareProcessor源码,截取最重要的片段:
		* 	if (bean instanceof Aware) {
		*   	if (bean instanceof EnvironmentAware) {
		*   		((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		* 		}
		* 		..类比..
		* 	}
		* 其实ApplicationContextAwareProcessor会帮我把几个特定类型做后置处理,填补上他们需要Aware的东西,
		* 比如上面的EnvironmentAware所想感知到的Environent
		* 我需要提醒一下,这是硬编码的BeanPostProcess,applicationContext维护了一个 beanPostProcessors:List<BeanPostProcessor>,他保存这些硬编码的BeanPostProcessor
		*/
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//设置Bean实例化时所需要忽略的自动装配的类型,即在依赖注入时,忽略他们
		//结合上面的这个ApplicationContextAwareProcessor,应该知道为什么了吧??
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);	##Look Here
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		//当注册了依赖解析后,当你在Bean中,注入了BeanFactory类型的值,或者ApplicationEventPublisher类型的值
		//那么,便会直接将beanFactory或者this给他注入进去
		//class servier{
		//	@Autowired
		//	private ApplicationEventPublisher publisher;
		//}
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
		//如果需要的话,添加AOP
		//<contexts:load-time-weaver />
		//containsBean获取查找是否有beanName为LOAD_TIME_WEAVER_BEAN_NAME的singleton或者beanDefinition
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// 为类型匹配设置一个临时的类加载器
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注册三个单例的Environment Bean,并设置beanName为environment/systemProperties/systemEnvironment
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

postProcessBeanFactory

	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

抽象模板方法,交给子类去覆写,到此时,ApplicationContext中的beanFactory已经完全的初始化完,这时候所有的BeanDefinition已经注册完,但是还没有实例化任何的Bean。此时允许自定义的子类中(就是你自己实现的ApplicationContext类中)去注册一些特定的BeanPostProcessors。

invokeBeanFactoryPostProcessors

	/**
	* 实例化并调用所有注册的BeanFactoryPostProcessors,
	* 如果BeanFactoryPostProcessor又显式的优先级,那么必须care
	* 一定要在singleton的bean实例化前执行它
	*/
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		//将实例化和调用的逻辑,委托给PostProcessorRegistrationDelegate
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		// 检测LoadTimeWeaver并为编织做准备,算是有点冗余,前面prepareBeanFactory步骤中其实都做了,但是不影响
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
	//获取硬编码的BeanFactoryPostProcessor,y一定要与配置的BeanFactoryPostProcessor区分开来
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

下面先看PostProcessorRegistrationDelegate到底是如何做的:

final class PostProcessorRegistrationDelegate {
	//代码题很长,但是逻辑很简单,查找,filter,排序,invoke
	//该方法入参有两个:
	//beanFactory:不多讲了
	//beanFactoryPostProcessors:注意哟,它的值是在AbstractApplicationContext中通过getBeanFactoryPostProcessors()方法
	//获取的,而beanFactoryPostProcessors是硬编码的BeanFactoryPostProcssor的列表(即通过AbstractApplicationContext.addBeanFactoryPostProcessor方法添加进去的)
	//硬编码的BeanFactoryPostFacry的优先级是最高的,比任何配置的BeanFactoryPostProcessor要高
	//您可能会问,那配置的硬编码的BeanFactoryPostProcessor在哪呢,他在我们的BeanDefinitionRegistry上注册着呢
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// BanFactoryPostProcessor接口是顶级接口,他的子接口BeanDefinitionRegistryPostProcessors在其上声明了一个额外的方法
		//即void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
		//我们要先执行BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry这个方法
		//然后在调用这些BanFactoryPostProcessor的postProcessBeanFactory方法
		//但是呢,Spring允许BeanDefinitionRegistryPostProcessors和postProcessBeanFactory的实现具有优先级(即实现Ordered或者PriorityOrdered),其中PriorityOrdered的又要比Ordered优先级高一点,优先级最低的是无序的BeanFactoryPostProcessor

		Set<String> processedBeans = new HashSet<>();
		//如果传入的BeanFactory实例是实现了BeanDefinitionRegistry的话
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//声明两个临时列表:
			//regularPostProcessors用于存储常规的BeanFactoryPostProcessor
			//registryProcessors则用于存储实现自BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//beanFactoryPostProcessors指的是硬编码的BeanFactoryPostProcessor,它的优先级是最高的,故而先执行
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//如果此硬编码的BeanFactoryPostProcessor是实现自BeanDefinitionRegistryPostProcessor,则将其加入到registryProcessors,并执行其特殊的
				//postProcessBeanDefinitionRegistry方法,否则,加入到regularPostProcessors中,并不执行任何方法,等最后再统一执行
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
			//beanFactory.getBeanNamesForType,根据类型,获取该类型的beanMame
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					//如果实现了PriorityOrdered,则将其add到currentRegistryProcessors,等待一会的排序和执行
					//并将beanName加入到processedBeans,以防止同一个bean,被调用多次
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//对currentRegistryProcessors排序,然后将其add到registryProcessors
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			//调用currentRegistryProcessors中的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空currentRegistryProcessors,本人觉得是一种不好的设计
			currentRegistryProcessors.clear();

			// Next, 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessors.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, 调用所有其他BeanDefinitionRegistryPostProcessors,知道没有任何一个BeanDefinitionRegistryPostProcessors出现为止.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, 调用到目前为止出现的所有BeanFactoryPostProcessor 的postProcessBeanFactory方法.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// 调用用上下文实例注册的工厂处理器。即硬编码的BeanFactoryPostProcessor
			//因为程序走到这里,也说明BeanFactory实例并非BeanDefinitionRegistry类型,因此优先级什么的也不care了
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// 分割BeanFactoryPostProcessors,按照PriorityOrdered > Ordered > 其他的顺序
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				//跳过,因为这表示该BeanFactoryPostProcessor也是一个BeanDefinitionRegistryPostProcessor,而他已经在前面被处理过了
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, 调用实现了PriorityOrdered接口的 BeanFactoryPostProcessors .
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, 调用实现了Ordered接口的 BeanFactoryPostProcessors .
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, 调用剩下下的 BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		//清理缓存的merged Bean定义,因为post-processors可能修改了原始元数据,例如替换值中的占位符……
		beanFactory.clearMetadataCache();
	}

}

概述:在实例化singleton的Bean之前,先调用BeanFactoryPostProcessor,以修改BenDifinition。ApplicationContext存在两种BeanFactoryPostProcessor,一种是硬编码的(即通过ApplicationContext的addBeanFactoryPostProcessor方法注册的),一种是配置的(即通过xml配置的)。先执行硬编码的BeanFactoryPostProcessor,Spring允许优先级,同时BeanDefinitionRegistryPostProcessor作为BeanFactoryPostProcessor的子接口,也拥有比纯BeanFactoryPostProcessor类型的实例更高的优先级。排序与执行,看注释即可。

registerBeanPostProcessors

	//实例化并注册所有BeanPostProcessor的Bean实例
	//优先级敏感
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

final class PostProcessorRegistrationDelegate {
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 在BeanPostPorocessor的链最开始,注册一个BeanPostProcessorChecker,他的作用是
		//在bean实例窗前的时候,打印日志,比如当:a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 将实现了PriorityOrdered、Ordered还有其他的 BeanPostProcessors分隔开来
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First,注册实现了 PriorityOrdered 的 BeanPostProcessors.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, 注册实现了Ordered接口的BeanPostProcessors.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now,注册所有的常规BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, 重新注册所有的内置BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 重新注册后置处理器ApplicationListenerDetector,该处理器会检测实现了ApplicationListener接口的bean,
		// 将其移动到处理器链的最后(用于获取代理等)
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
}

概述:代码较长,但是干的工作也很简单,获取所有配置的BeanPostProcssor,然后按照PriorityOrdered > Ordered > 其他的顺序,调用beanFactory.addBeanPostProcessor(postProcessor)方法进行注册。因为BeanPostProcessor并不在此时执行,所以这里做的工作只是实例化、注册。

BeanPostProcessor是在实例化Bean时候init-method执行前后才会被调用哟,详细见Bean加载的讲解。

initMessageSource()

国际化相关

initApplicationEventMulticaster()

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}
	//注册监听者
	protected void registerListeners() {
		// 首先注册静态指定的监听者。
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 这里不初始化FactoryBean:我们需要不初始化所有常规bean,而是让后置处理程序应用于它们!
		//这里只是将beanName注册到了广播器上,即注册配置方式注册的监听者的beanName
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 发布事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
	//广播事件
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		Executor executor = getTaskExecutor();
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}
	}
}

概述:如果用户自定义了事件广播器,那么使用用户定义的,否则使用SimpleApplicationEventMulticaster这个ApplicationEventMulticaster默认实现,来作为applicationEventMulticaster变量的值,并将其注册到beanFactory的单例缓存中。

onRefresh()

对Web的ApplicationContext至关重要,在特定上下文子类中初始化其他特殊bean。

registerListeners()

	protected void registerListeners() {
		// 注册静态(硬编码)的特定监听器.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			//注册
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 注册配置的监听者的BeanName,先不实例化他们
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			//注册
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 发射一个earlyEvent
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

finishBeanFactoryInitialization(beanFactory)

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 我当前上下文环境初始化转换服务,ConversionService
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		//如果此时没有注册任何一个解析属性值的后置处理器, 那么就注册一个默认的内嵌属性值解析器。
		//此时,只要用于解析注解中的值
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		//停止使用临时类加载器进行类型匹配。
		beanFactory.setTempClassLoader(null);

		// 缓存bean的定义(BanDefinition),不会再修改他们了
		beanFactory.freezeConfiguration();

		// 实例化所有剩余的(非lazy-init的)单例。
		beanFactory.preInstantiateSingletons();
	}

概述:在该方法中完成BeanFactory的初始化工作,

  1. 首先检查ConversionService,那段是否有名字

    为"conversionService"或者ConversionService类型的BeanDefinition存在,如果存在,则设置为beanFactory的conversionService变量的值。

  2. 判断当前的beanFactory是否有内嵌属性值解析器,如果不存在,则赋一个默认的解析器

  3. 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。

  4. 停止对临时类加载器的使用

  5. 冻结所有的beanDefinition,暗示以后不会再修改它们了

  6. 实例化所有的单例Bean(排除lazy-init)

finishRefresh()

	protected void finishRefresh() {
		// 清理上下文级别的Rsource资源 (such as ASM metadata from scanning).
		clearResourceCaches();

		// 为当前上下文初始化生命周期处理器
		initLifecycleProcessor();

		// 首先将refresh传播到生命周期处理器上.
		getLifecycleProcessor().onRefresh();

		//发送终极事件.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}
	protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//判断上下文是否存在“lifecycleProcessor”的BanDefinition
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			//实例化一个默认的生命周期处理器
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}
	private void startBeans(boolean autoStartupOnly) {
		//获取所有实现了Lifecycle的Ban
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new HashMap<>();
		//循环启动刷新
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			List<Integer> keys = new ArrayList<>(phases.keySet());
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}
	//从当前上下文的底层BeanFactory中获取所有实现了Lifecycle的Bean
	protected Map<String, Lifecycle> getLifecycleBeans() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		Map<String, Lifecycle> beans = new LinkedHashMap<>();
		String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
		for (String beanName : beanNames) {
			String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
			boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
			String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
			if ((beanFactory.containsSingleton(beanNameToRegister) &&
					(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
					matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
				Object bean = beanFactory.getBean(beanNameToCheck);
				if (bean != this && bean instanceof Lifecycle) {
					beans.put(beanNameToRegister, (Lifecycle) bean);
				}
			}
		}
		return beans;
	}
}

概述:Spring中提供了lifecycle接口,而该接口声明了start/stop方法,实现此接口的Bean,Spring会在启动时调用其start方法,在Sring关闭时调用stop方法,以开启和关闭生命周期。

好了,ioc容器的创建过程就是这个样子,后面再详细的写一下aop的原理与bean的生命周期完善一下就差不多了。其他的细节就需要自己慢慢细看了

参考:
https://blog.csdn.net/qq_31179577/article/details/100693282
https://blog.csdn.net/nuomizhende45/article/details/81158383/

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 23:04:10  更:2021-08-10 23:04:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 5:25:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码