Spring BeanFactory、ApplicationContext层次结构和BeanDefinition解析过程

先说层次架构

// 水桶和上下文类层次概要(还有如何打水)


// 当你在使用FileSystemXmlApplicationContext之类的类时,你会感觉里面的方法调用错综复杂,层次很多。
// 那么,我们先从主要类的作用和层次说起,让我们有个大体的概念和印象,便于后面的分析。

class Waterpot {
	// 水桶:
	// 顺序基本是按照继承的先后顺序

	// ***************************基本接口定义分支***************************

	// ==================最基本的两个接口=============================

	// 接口:最基本的,就是包括一些bean的获取,bean类型判断,别名数组获取等
	// *org.springframework.beans.factory.BeanFactory

	// 接口:和他的名字Hierarchical一样,分层用的,获取父的beanFactory,和判断beanfactory是否存在指定的bean
	// *org.springframework.beans.factory.HierarchicalBeanFactory

	// ===========ConfigurableBeanFactory:bean factory的主要相关资源管理========

	// 接口:HierarchicalBeanFactory的其中一种直接父接口(还包括ApplicationContext,也是HierarchicalBeanFactory的一种直接父接口)
	// 他的方法定义就比较多,包括(应该主要是bean factory操作需要的一些场景资源和环境指定等):
	// 设置beanfactory用的双亲(parentBeanFactory)、ClassLoader赋值、tempClassLoader赋值、Set
	// whether to cache bean metadata such as given bean definitions (in
	// merged fashion) and resolved bean
	// classes.、TypeConverter赋值、添加BeanPostProcessor等
	// *org.springframework.beans.factory.config.ConfigurableBeanFactory

	// ===ConfigurableListableBeanFactory:对configurable、list、autowire的继承包含(主要就是对环境定义的深入整合)====

	// 接口:前面做到了bean factory对bean的单个操作,这个主要是返回和操作多个返回结果
	// *org.springframework.beans.factory.ListableBeanFactory

	// 接口:自动IoC注解的相关操作
	// *org.springframework.beans.factory.config.AutowireCapableBeanFactory

	// 接口:主要是对前面主要接口的总结,并提供了preInstantiateSingletons方法。
	// 主要还包括了,对自动装配的额外定义:忽略类型、忽略接口、指定绑定等
	// *org.springframework.beans.factory.config.ConfigurableListableBeanFactory

	// ***************************额外特殊接口和实现分支***************************

	// ====================各种bean注册==============================
	// 接口:别名操作的定义
	// *org.springframework.core.AliasRegistry

	// 实现:对别名的管理(主要是维护了别名的map)
	// *org.springframework.core.SimpleAliasRegistry

	// 接口:单例方式bean的管理定义,包括注册获取和判断等
	// *org.springframework.beans.factory.config.SingletonBeanRegistry

	// 实现:继承了别名管理实现,并实现了单例注册(自己主要实现了单例注册接口,并管理着各种类型数据的map集合)
	// *org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

	// 接口:主要是对BeanDefinition的注册相关定义(BeanDefinition是bean的第二步原始数据--第一步dom解析数据)
	// *org.springframework.beans.factory.support.BeanDefinitionRegistry

	// ***************************各种接口的整合实现***************************

	// =========================对各种原始数据的操作==================================

	// 实现:对单例的获取和维护,对DefaultSingletonBeanRegistry进行了封装
	// *org.springframework.beans.factory.support.FactoryBeanRegistrySupport

	// 实现:实现了ConfigurableBeanFactory,也就是对资源管理的实现。且对FactoryBeanRegistrySupport继承,做了对bean获取的更进一步封装。
	// 这里已经不局限于单例的获取,还包括非单例,从父工厂获取判断等
	// *org.springframework.beans.factory.support.AbstractBeanFactory

	// 实现:对AutowireCapableBeanFactory接口的实现,并继承了AbstractBeanFactory
	// *org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

	// 实现:我们主要的基本容器实现。(再往下走会有各种applicationContext),但是原始数据BeanDefinition的水桶和单例的水桶主要就是DefaultListableBeanFactory
	// *org.springframework.beans.factory.support.DefaultListableBeanFactory
}

class Context {
	// 上下文

	// =========================最底层上下文:ApplicationContext==================================

	// 接口:环境Environment的获取
	// *org.springframework.core.env.EnvironmentCapable

	// 接口:参数化和国际化等消息的支持下解决的消息,策略接口。
	// *org.springframework.context.MessageSource

	// 接口:接收ApplicationEvent
	// *org.springframework.context.ApplicationEventPublisher

	// 接口:获取资源
	// *org.springframework.core.io.support.ResourcePatternResolver

	// 接口:上下文最基础的接口,除继承了上面的接口外,还继承了容器的ListableBeanFactory,
	// HierarchicalBeanFactory的两个接口
	// *org.springframework.context.ApplicationContext

	// ==============================ConfigurableApplicationContext=======================================
	// 接口:The typical use case for this is to control asynchronous processing.
	// 很多执行控制接口都继承自本接口
	// *org.springframework.context.Lifecycle

	// 接口:从ApplicationContext继承了上下文的基本功能外,又定义了大量的环境配置接口(包括:setEnvironment、addBeanFactoryPostProcessor、addApplicationListener、registerShutdownHook)。还有主要的入口refresh()
	// *org.springframework.context.ConfigurableApplicationContext

	// ==============================上线文基本方法实现:AbstractApplicationContext=======================================

	// 接口:销毁动作,销毁单例类
	// *org.springframework.beans.factory.DisposableBean

	// 接口:加载资源的策略接口
	// *org.springframework.core.io.ResourceLoader

	// 实现:默认的资源加载
	// *org.springframework.core.io.DefaultResourceLoader

	// 实现:上线文基本方法实现(包括加载和刷新的入口、初始化容器开始时间等、刷新重建BeanFactory入口(具体的refreshBeanFactory留由子类完成)、准备bean
	// factory(主要声明了classLoader、添加BeanPostProcessor
	// 、自动装配忽略接口、自动装配类型匹配指定、注册各种单例等)、调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
	// 、对上下文中的消息源进行初始化、初始化上下文中的事件机制、检查监听bean并且将这些bean向容器注册、实例化所有的(non-lazy-init)单例、发布容器事件,结束Refresh过程)
	// *org.springframework.context.support.AbstractApplicationContext

	// ==============================刷新和重建BeanFactory:AbstractRefreshableApplicationContext==================
	// 实现:比较重要的实现方法refreshBeanFactory,刷新和重建BeanFactory
	// *org.springframework.context.support.AbstractRefreshableApplicationContext

	// ==============================AbstractRefreshableConfigApplicationContext==============================

	// 接口:bean factory的名称
	// *org.springframework.beans.factory.BeanNameAware

	// *org.springframework.beans.factory.InitializingBean

	// 实现:Config的设置
	// *org.springframework.context.support.AbstractRefreshableConfigApplicationContext

	// ==============================AbstractXmlApplicationContext==============================

	// 实现:主要是loadBeanDefinitions的实现,内部指定XmlBeanDefinitionReader方式读取
	// *org.springframework.context.support.AbstractXmlApplicationContext

	// ClassPathXmlApplicationContext、FileSystemXmlApplicationContext
	// 启动入口和“个性”资源加载
}

// =====================================================解析相关============================================


// 解析第一步:读取资源

class Reader {

	// ===================================资源读取:XmlBeanDefinitionReader===================================
	// 分析下XmlBeanDefinitionReader组织层次

	// 接口:读取解析的基础接口,主要就是四个loadBeanDefinitions定义,负责读取的定义,但是不包含读取后的注册定义等。
	// *org.springframework.beans.factory.support.BeanDefinitionReader

	// 实现:简单封装实现了BeanDefinitionReader(String类型资源加载、Resource多参数遍历、各种资源的获取和赋值定义)和EnvironmentCapable两个接口。
	// (具体如何读取交给了子类包含Resource参数的接口定义中去完成)
	// *org.springframework.beans.factory.support.AbstractBeanDefinitionReader

	// 实现:XML格式文件读取,最终实现提供类。具体指定了读取规则,和注册规则。(具体的读取和注册还要往下走)
	// *org.springframework.beans.factory.xml.XmlBeanDefinitionReader
}

// 解析第二步:Document读取
// DefaultDocumentLoader,dom解析就不说了,和我们平时做dom解析应该没太大区别,我们平时可以借助很多不错的第三方框架。


// 解析第二步半:BeanDefinitionDocumentReader(资源整合,或者说功能抽取)

class MyBeanDefinitionDocumentReader {
	// ===================================通过Reader返回的Document获取注册匹配的BeanDefinition:BeanDefinitionDocumentReader=========================

	// 接口:SPI for parsing an XML document that contains Spring bean definitions.
	// Used by XmlBeanDefinitionReader for actually parsing a DOM document.
	// *org.springframework.beans.factory.xml.BeanDefinitionDocumentReader

	// 实现:供Reader调用。结合了DocumentLoader读取的Document和XmlReaderContext。
	// *org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
}

// 解析第三步:通过Document解析成BeanDefinition

class MyBeanDefinitionParserDelegate {
	// 工具类:根绝规则做的各种解析方法
	// *org.springframework.beans.factory.xml.BeanDefinitionParserDelegate
	// 然后就是通过工具类,帮助封装注册进DefaultListableBeanFactory
}




再说执行过程


==============================FileSystemXmlApplicationContext==============================


*org.springframework.context.support.FileSystemXmlApplicationContext


比较常用的ApplicationContext有多种,我们选择一种FileSystemXmlApplicationContext进行入口分析。(几种ApplicationContext实现的区分基本在于资源获取方式和解析方式不同)


创建:

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {
	
	super(parent);
	//设置资源路径,由子类AbstractRefreshableConfigApplicationContext完成
	setConfigLocations(configLocations);
	//Load or refresh the persistent representation of the configuration, which might an XML file, properties file, or relational database schema. 
	//进行了加载资源,销毁以前容器,创建容器,资源解析,Instantiate all remaining (non-lazy-init) singletons,
	if (refresh) {
		refresh();
	}
}

*1:refresh():(由最基础实现类AbstractApplicationContext提供)

public void refresh() throws BeansException, IllegalStateException {  
    synchronized (this.startupShutdownMonitor) {  
        // Prepare this context for refreshing.  
        prepareRefresh();  
  
        // Tell the subclass to refresh the internal bean factory.  
        //这里是在子类中启动refreshBeanFactory()的地方  
        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.  
            //设置BeanFactory的后置处理  
            postProcessBeanFactory(beanFactory);  
  
            // Invoke factory processors registered as beans in the context.  
            //调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的  
            invokeBeanFactoryPostProcessors(beanFactory);  
  
            // Register bean processors that intercept bean creation.  
            //注册Bean的后处理器,在bean的创建过程中被调用  
            registerBeanPostProcessors(beanFactory);  
  
            // Initialize message source for this context.  
            //对上下文中的消息源进行初始化  
            initMessageSource();  
  
            // Initialize event multicaster for this context.  
            //初始化上下文中的事件机制  
            initApplicationEventMulticaster();  
  
            // Initialize other special beans in specific context subclasses.  
            //初始化其他的特殊bean  
            onRefresh();  
  
            // Check for listener beans and register them.  
            //检查监听bean并且将这些bean向容器注册  
            registerListeners();  
  
            // Instantiate all remaining (non-lazy-init) singletons.  
            //实例化所有的(non-lazy-init)单例  
            finishBeanFactoryInitialization(beanFactory);  
  
            // Last step: publish corresponding event.  
            //发布容器事件,结束Refresh过程  
            finishRefresh();  
        }  
  
        catch (BeansException ex) {  
            // Destroy already created singletons to avoid dangling resources.  
            destroyBeans();  
  
            // Reset 'active' flag.  
            cancelRefresh(ex);  
  
            // Propagate exception to caller.  
            throw ex;  
        }  
    }  
}  

**1.1:容器获取、数据解析入口:obtainFreshBeanFactory()具体实现refreshBeanFactory()留给子类实现
(因为AbstractApplicationContext就是具体的通用的资源准备,具体的计息读取规则应该由各分支子类实现):
AbstractRefreshableApplicationContext---refreshBeanFactory

@Override  
protected final void refreshBeanFactory() throws BeansException {  
    //这里判断,如果已经建立BeanFactory,则销毁并关闭该BeanFactory  
    if (hasBeanFactory()) {  
        destroyBeans();  
        closeBeanFactory();  
    }  
    //这里是创建并设置持有的DefaultListableBeanFactory的地方同时调用loadBeanDefinitions(beanFactory)再载入BeanDefinition的信息。  
    try {  
        DefaultListableBeanFactory beanFactory = createBeanFactory();  
        beanFactory.setSerializationId(getId());  
        //BeanFactoryAware等资源的配置
        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);  
    }  
}  


***1.1.1:需要注意的是我们以后要用的BeanFactory--DefaultListableBeanFactory:

protected DefaultListableBeanFactory createBeanFactory() {
(也就是水桶,具体的水桶并不由ApplicationContext提供,而是由BeanFactory分支实现提供)
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

****1.1.1.1:创建之后会赋值给AbstractRefreshableApplicationContext的变量:

/** Bean factory for this context */
private DefaultListableBeanFactory beanFactory;

****1.1.1.2:并实现了AbstractApplicationContext声明的获取方法:

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
	synchronized (this.beanFactoryMonitor) {
		if (this.beanFactory == null) {
			throw new IllegalStateException("BeanFactory not initialized or already closed - " +
					"call 'refresh' before accessing beans via the ApplicationContext");
		}
		return this.beanFactory;
	}
}

****1.1.1.3:同步的锁:

/** Synchronization monitor for the internal BeanFactory */
private final Object beanFactoryMonitor = new Object();



***1.1.2加载解析Bean的原始封装数据:BeanDefinitions -- loadBeanDefinitions(beanFactory)
这里主要指定了读取工具类(XmlBeanDefinitionReader),和执行解析入口。因为,我们的配置可以是多种形式的,这里需要具体资源形式的子类(AbstractXmlApplicationContext)去实现。
AbstractXmlApplicationContext:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// Create a new XmlBeanDefinitionReader for the given BeanFactory.
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// Configure the bean definition reader with this context's
	// resource loading environment.
	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);
}

****1.1.2.1这里的application environment的值是由最开始FileSystemXmlApplicationContext构造器中super(parent),一路调用父类构造器,最终在
AbstractApplicationContext中实现:

public AbstractApplicationContext(ApplicationContext parent) {
	this.parent = parent;
	this.resourcePatternResolver = getResourcePatternResolver();
	this.environment = this.createEnvironment();
}

/**
 * Create and return a new {@link StandardEnvironment}.
 * <p>Subclasses may override this method in order to supply
 * a custom {@link ConfigurableEnvironment} implementation.
 */
protected ConfigurableEnvironment createEnvironment() {
	return new StandardEnvironment();
}

****1.1.2.2ResourceLoader是通过继承获得(AbstractApplicationContext extends DefaultResourceLoader)

****1.1.2.3EntityResolver:Allow the application to resolve external entities. 
通过下面两个常量,我们可以猜是对格式规范的读取

public class DelegatingEntityResolver implements EntityResolver {

	/** Suffix for DTD files */
	public static final String DTD_SUFFIX = ".dtd";

	/** Suffix for schema definition files */
	public static final String XSD_SUFFIX = ".xsd";
	
	public DelegatingEntityResolver(ClassLoader classLoader) {
		this.dtdResolver = new BeansDtdResolver();
		this.schemaResolver = new PluggableSchemaResolver(classLoader);
	}	
...
}	


****1.1.2.4为XmlBeanDefinitionReader准备好各种所需的资源后,就开始真正解析了:
这里是对我们前面赋值的资源便利读取:

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

*********1.1.2.4.1目前主要是下面那个String[]数组。
赋值的地方在AbstractRefreshableConfigApplicationContext(这也是我们为什么在AbstractRefreshableApplicationContext的基础上有多了个AbstractRefreshableConfigApplicationContext原因,单独为资源赋值形式抽取封装):

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++) {
			this.configLocations[i] = resolvePath(locations[i]).trim();
		}
	}
	else {
		this.configLocations = null;
	}
}

此方法调用是在我们上面的FileSystemXmlApplicationContext构造器中。
(所以到这里,可以看到,我们上面出现了很多很多不同地方,不同形式的赋值,这些赋值在以后的解析等过程中进行了各自的作用)




到这里我们ApplicationContext关于解析的工作告一段落,然后就是XmlBeanDefinitionReader如何具体解析:
上面准备了和计算出了很多环境条件,然后接下来就是具体的如何通过Xml解析成最初的Bean类型BeanDefinition


===================================解析===================================
1、开始是一连串的AbstractBeanDefinitionReader处理,做了他可以做的事情之后,具体的又交给了父类,也就是上面指定的XmlBeanDefinitionReader
2、XmlBeanDefinitionReader也有做了一大串的判断,在doLoadBeanDefinitions方法中调用了DefaultDocumentLoader的loadDocument获取了Document
3、然后又把一些资源和Document传给了DefaultBeanDefinitionDocumentReader,DefaultBeanDefinitionDocumentReader又做了一些介于Reader和纯Document解析之间的一些工作,包括各种解析判断走向什么的。
4、然后又通过BeanDefinitionParserDelegate,BeanDefinitionParserDelegate只接收了Element,根绝我们的规则解析出了BeanDefinitionHolder
5、最后我们又通过BeanDefinitionReaderUtils,把我们解析出的BeanDefinition注解进我们的容器DefaultListableBeanFactory。

你可能感兴趣的:(Spring BeanFactory、ApplicationContext层次结构和BeanDefinition解析过程)