Spring IoC的细节--AbstractBeanDefinitionReader.getResourceLoader()

AbstractBeanDefinitionReader:

    public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
        //获取资源加载器,该资源加载器事实上是ClassPathXmlApplicationContext对象,从哪里得知呢?
		ResourceLoader resourceLoader = getResourceLoader(); //代码1
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
		}
		
		//由于ClassPathXmlApplicationContext实现ResourcePatternResolver,将执行以下分支
		if (resourceLoader instanceof ResourcePatternResolver) {
			try {
			    //将字符串类型的配置文件转换为Spring能识别的Resource对象资源
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);//代码2
				//进入重载的loadBeanDefinitions(Resource..)方法
				//最终调用由XmlBeanDefinitionReader实现的loadBeanDefinitions(Resource resource)方法
				//主线
				int loadCount = loadBeanDefinitions(resources);
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				...
				return loadCount;
			}
			catch (IOException ex) {
                ...
			}
		}
		else {
			//仅可以从绝对路径加载单独的resource
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
            ...
			return loadCount;
		}
	}

代码1的调用细节如下:

    @Nullable
	private ResourceLoader resourceLoader;
    
    @Override
	@Nullable
	public ResourceLoader getResourceLoader() {
		return this.resourceLoader;
	}

成员变量resourceLoader分别有以下的赋值时机:

构造器初始化:

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

		// Determine ResourceLoader to use.
		if (this.registry instanceof ResourceLoader) {
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}

		// Inherit Environment if possible
		if (this.registry instanceof EnvironmentCapable) {
			this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
		}
		else {
			this.environment = new StandardEnvironment();
		}
	}

set方法:

    public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

此时我们回顾一下IoC的时候,是如何创建XmlBeanDefinitionReader对象的,以下代码回顾一下:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

		//创建一个Xml的BeanDefinition的读取器
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //代码1

		//为BeanDefinition读取器配置当前上下文的资源加载环境
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);    //代码2
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		//允许子类提供BeanDefinition的自定义初始化功能
		initBeanDefinitionReader(beanDefinitionReader);
		//执行事实上的加载
		loadBeanDefinitions(beanDefinitionReader);
	}

上述代码1和代码2其实都对resourceLoader进行了赋值操作,但是代码2在后面,因此最终resourceLoader为beanDefinitionReader.setResourceLoader(this)赋予的this值,此时的this的值为ClassPathXmlApplicationContext对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值