Spring源码解析之配置读取器加载流程解析

导读:本篇文章讲解 Spring源码解析之配置读取器加载流程解析,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

前文

在之前介绍了资源与工厂创建流程解析,但是这两者Spring创建好之后并没有关联,因为我们光读取是不够的,往哪读,这是这一章要阐述的!

读取核心代码

//bean定义的读取器
BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(defaultBeanFactory);

BeanDefinitionReader按照源码注释里说的“是为了bean定义阅读的一个简单接口,使用Resource和String位置参数指定加载方法。”

我们再细看XmlBeanDefinitionReader进入构造方法向上看父类里的方法:

	protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		// Determine ResourceLoader to use.
		//这个bean的注册表对象是否是ResourceLoader的实例
		if (this.registry instanceof ResourceLoader) {
			//如果是那么就把这个注册bean的对象赋值给当前对象的ResourceLoader属性
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			//否则给他一个默认的资源加载器
			//this.resourceLoader = new DefaultResourceLoader();
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}

		// Inherit Environment if possible
		//和上面一样判断bean的注册对象是否是EnvironmentCapable的实例
		if (this.registry instanceof EnvironmentCapable) {
			//是的话,就获取环境对象并进行赋值
			this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
		}
		else {
			//没有相应方法的话就给与一个标准环境
			this.environment = new StandardEnvironment();
		}
	}

这里面有一个比较重要的对象Environment,进去看一下源码,就会发现他继承PropertyResolver,对profile的操作
在这里插入图片描述
进入他的继承类发现他主要是对Property属性进行操作在这里插入图片描述
然后在看StandardEnvironment对象:
在这里插入图片描述
我们可以看到他的上层也是实现了Environment接口,里面没有对应的构造函数!至此为止,AbstractBeanDefinitionReader构造完成!

读取器的加载

beanDefinitionReader.loadBeanDefinitions(resource);

进入源码:

	/**
	 * Load bean definitions from the specified resource.
	 * @param resource the resource descriptor
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	//bean的解析数量
	int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;

它是一个接口,我们查看他的实现类XmlBeanDefinitionReader:

	/**
	 * Load bean definitions from the specified XML file.
	 * @param resource the resource descriptor for the XML file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	@Override
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}

我们先看看EncodedResource对资源到底做了什么?这里我们直接进到核心代码块:
**加粗样式**

	private EncodedResource(Resource resource, @Nullable String encoding, @Nullable Charset charset) {
		super();
		Assert.notNull(resource, "Resource must not be null");
		this.resource = resource;
		this.encoding = encoding;
		this.charset = charset;
	}

把传入的resource赋值给当前的Resource对象,返回回去!这是第一步!然后进入loadBeanDefinitions方法:

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

		//ThreadLocal<Set<EncodedResource>>,他返回一个初始值为4的hashset集合
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		//判断是否会产生循环依赖
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}

		//下面的代码下一章会重点说明
		try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
			InputSource inputSource = new InputSource(inputStream);
			if (encodedResource.getEncoding() != null) {
				inputSource.setEncoding(encodedResource.getEncoding());
			}
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}

这里面资源解析读取与加载完成之后,后面就是调用者如何使用的问题了!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16384.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!