基于Xml 的IOC 容器-分配路径处理策略

在XmlBeanDefinitionReader 的抽象父类AbstractBeanDefinitionReader 中定义了载入过程。

AbstractBeanDefinitionReader 的loadBeanDefinitions()方法源码如下:

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
	//获取在IoC容器初始化过程中设置的资源加载器
	ResourceLoader resourceLoader = getResourceLoader();
	if (resourceLoader == null) {
		throw new BeanDefinitionStoreException(
				"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
	}

	if (resourceLoader instanceof ResourcePatternResolver) {
		// Resource pattern matching available.
		try {
			//将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源
			//加载多个指定位置的Bean定义资源文件
			Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
			//委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
			int loadCount = loadBeanDefinitions(resources);
			if (actualResources != null) {
				for (Resource resource : resources) {
					actualResources.add(resource);
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
			}
			return loadCount;
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"Could not resolve bean definition resource pattern [" + location + "]", ex);
		}
	}
	else {
		// Can only load single resources by absolute URL.
		//将指定位置的Bean定义资源文件解析为Spring IOC容器封装的资源
		//加载单个指定位置的Bean定义资源文件
		Resource resource = resourceLoader.getResource(location);
		//委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
		int loadCount = loadBeanDefinitions(resource);
		if (actualResources != null) {
			actualResources.add(resource);
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
		}
		return loadCount;
	}
}

//重载方法,调用loadBeanDefinitions(String);
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
	Assert.notNull(locations, "Location array must not be null");
	int counter = 0;
	for (String location : locations) {
		counter += loadBeanDefinitions(location);
	}
	return counter;
}

AbstractRefreshableConfigApplicationContext 的loadBeanDefinitions(Resource...resources) 方法实际上是调用AbstractBeanDefinitionReader 的loadBeanDefinitions()方法。

从对AbstractBeanDefinitionReader 的loadBeanDefinitions()方法源码分析可以看出该方法就做了两件事:

首先,调用资源加载器的获取资源方法resourceLoader.getResource(location),获取到要加载的资源。其次,真正执行加载功能是其子类XmlBeanDefinitionReader 的loadBeanDefinitions()方法。在loadBeanDefinitions()方法中调用了AbstractApplicationContext 的getResources()方法,跟进去之后发现getResources()方法其实定义在ResourcePatternResolver 中,此时,我们有必要来看一下ResourcePatternResolver 的全类图:

从上面可以看到ResourceLoader 与ApplicationContext 的继承关系,可以看出其实际调用的是DefaultResourceLoader 中的getSource() 方法定位Resource , 因为ClassPathXmlApplicationContext 本身就是DefaultResourceLoader 的实现类,所以此时又回到了
ClassPathXmlApplicationContext 中来。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值