基于 xml 的 IOC 容器的初始化(未完善)

寻找入口

ClassPathXmlApplicationContext

在这里插入图片描述

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

	// 寻找入口
	super(parent);
	// 获得配置路径
	setConfigLocations(configLocations);
	if (refresh) {
    
    
		// 开始启动
		refresh();
	}
}

获得配置路径

AbstractApplicationContext

在这里插入图片描述

public AbstractApplicationContext(@Nullable ApplicationContext parent) {
    
    
	this();
}
public AbstractApplicationContext() {
    
    
	this.resourcePatternResolver = getResourcePatternResolver();
}
/**
 * 获取一个Spring Source的加载器用于读入Spring Bean定义资源文件
 * @return
 */
protected ResourcePatternResolver getResourcePatternResolver() {
    
    
	//AbstractApplicationContext 继承 DefaultResourceLoader,因此也是一个资源加载器
	//Spring 资源加载器,其 getResource(String location) 方法用于载入资源
	return new PathMatchingResourcePatternResolver(this);
}

PathMatchingResourcePatternResolver

在这里插入图片描述

public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
    
    
	Assert.notNull(resourceLoader, "ResourceLoader must not be null");
	//设置Spring的资源加载器
	this.resourceLoader = resourceLoader;
}

AbstractRefreshableConfigApplicationContext

在这里插入图片描述

/**
 * 解析 Bean 定义资源文件的路径,处理多个资源文件字符串数组
 * @param locations
 */
public void setConfigLocations(@Nullable String... locations) {
    
    
}

开始启动

AbstractApplicationContext

@Override
public void refresh() throws BeansException, IllegalStateException {
    
    
	//2、告诉子类启动 refreshBeanFactory() 方法,Bean定义资源文件的载入从
	//子类的 refreshBeanFactory() 方法启动
	ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
}

创建容器

AbstractApplicationContext

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    
    
	//这里使用了委派设计模式,父类定义了抽象的 refreshBeanFactory() 方法,
	//具体实现调用子类容器的refreshBeanFactory()方法
	refreshBeanFactory();
}

AbstractRefreshableApplicationContext

protected final void refreshBeanFactory() throws BeansException {
    
    
	//调用载入Bean定义的方法,主要这里又使用了一个委派模式,
	//在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
	loadBeanDefinitions(beanFactory);
}

载入配置路径

AbstractXmlApplicationContext

/**
 * 实现父类抽象的载入Bean定义方法, 载入配置路径
 * @param beanFactory the bean factory to load bean definitions into
 * @throws BeansException
 * @throws IOException
 */
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    
    
	//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制
	initBeanDefinitionReader(beanDefinitionReader);
	//Bean读取器真正实现加载的方法
	loadBeanDefinitions(beanDefinitionReader);
}
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
    
    
}
/**
 * Xml Bean读取器加载Bean定义资源
 * @param reader
 * @throws BeansException
 * @throws IOException
 */
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    
    
	//获取Bean定义资源的定位
	Resource[] configResources = getConfigResources();

	//Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源
	reader.loadBeanDefinitions(configLocations);
}
/**
 * 这里又使用了一个委托模式,调用子类的获取Bean定义资源定位的方法
 * 该方法在ClassPathXmlApplicationContext中进行实现,对于我们
 * 举例分析源码的FileSystemXmlApplicationContext没有使用该方法
 * @return
 */
@Nullable
protected Resource[] getConfigResources() {
    
    
	return null;
}

分配路径处理策略

AbstractBeanDefinitionReader

/**
 * 重载方法,调用loadBeanDefinitions(String);
 * @param locations the resource locations, to be loaded with the ResourceLoader
 * (or ResourcePatternResolver) of this bean definition reader
 * @return
 * @throws BeanDefinitionStoreException
 */
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    
    
	loadBeanDefinitions(location);
}
/**
 * 重载方法,调用下面的loadBeanDefinitions(String, Set<Resource>);方法
 * @param location the resource location, to be loaded with the ResourceLoader
 * (or ResourcePatternResolver) of this bean definition reader
 * @return
 * @throws BeanDefinitionStoreException
 */
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    
    
return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    
    
	if (resourceLoader instanceof ResourcePatternResolver) {
    
    
		//委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
		int loadCount = loadBeanDefinitions(resources);
	}else {
    
    
		//将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源
		//加载单个指定位置的Bean定义资源文件
		Resource resource = resourceLoader.getResource(location);
	}
}

解析配置文件路径

DefaultResourceLoader

/**
 * 获取Resource的具体实现方法
 * @param location the resource location
 * @return
 */
@Override
public Resource getResource(String location) {
    
    
	//如果是类路径的方式,那需要使用	ClassPathResource 来得到bean 文件的资源对象
	if (location.startsWith("/")) {
    
    
		return getResourceByPath(location);
	}
}
protected Resource getResourceByPath(String path) {
    
    
	return new ClassPathContextResource(path, getClassLoader());
}

开始读取配置内容

AbstractBeanDefinitionReader

/**
 * 重载方法, 调用 loadBeanDefinitions(String);
 * @param resources the resource descriptors
 * @return
 * @throws BeanDefinitionStoreException
 */
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    
    
	counter += loadBeanDefinitions(resource);
}

XmlBeanDefinitionReader

/**
 * XmlBeanDefinitionReader加载资源的入口方法
 * @param resource the resource descriptor
 * @return
 * @throws BeanDefinitionStoreException
 */
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    
    
	//将读入的XML资源进行特殊编码处理
	return loadBeanDefinitions(new EncodedResource(resource));
}
/**
 * 这里是载入XML形式Bean定义资源文件方法
 * @param encodedResource
 * @return
 * @throws BeanDefinitionStoreException
 */
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    
    
	//这里是具体的读取过程
	return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
/**
 * 从特定XML文件中实际载入Bean定义资源的方法
 * @param inputSource
 * @param resource
 * @return
 * @throws BeanDefinitionStoreException
 */
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
		throws BeanDefinitionStoreException {
    
    
	//将XML文件转换为DOM对象,解析过程由documentLoader实现
	Document doc = doLoadDocument(inputSource, resource);
}

准备文档对象

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
    
    
	return this.documentLoader.loadDocument(inputSource, 
											getEntityResolver(),
											this.errorHandler,
											getValidationModeForResource(resource), 
											isNamespaceAware());
	}

DefaultDocumentLoader

/**
 * 使用标准的JAXP将载入的Bean定义资源转换成document对象
 * @param inputSource the source of the document that is to be loaded
 * @param entityResolver the resolver that is to be used to resolve any entities
 * @param errorHandler used to report any errors during document loading
 * @param validationMode the type of validation
 * {@link org.springframework.util.xml.XmlValidationModeDetector#VALIDATION_DTD DTD}
 * or {@link org.springframework.util.xml.XmlValidationModeDetector#VALIDATION_XSD XSD})
 * @param namespaceAware {@code true} if support for XML namespaces is to be provided
 * @return
 * @throws Exception
 */
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
		ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
    
    
	
}

分配解析策略

将配置载入内存

载入元素

载入元素

载入的子元素

载入的子元素

分配注册策略

向容器注册

猜你喜欢

转载自blog.csdn.net/qq_44226094/article/details/119120465