Spring源码解读 :IOC容器实现BeanDefinitionReader篇(四)

通过前面的学习,我们已经获得对象的位置信息(Resource)和对象的定义,我们现在要做的就是去了解这个妹子,毕竟追妹子不是那么容易的,必须要对她进行深入分析,才有可能拿下她。

BeanDefinitionReader会告诉我们你追求的妹子是个什么样子的人。

public interface BeanDefinitionReader {
	
	/**
	 * 注册BeanDefinition,它是干嘛的呢,比如你追求的妹子,她叫小花,通过小花你就能找到那个妹子
	 */
	BeanDefinitionRegistry getRegistry();
	
	/**
	 * 资源加载器,让你可以见到你所追求的妹子
	 */
	ResourceLoader getResourceLoader();
	
	/**
	 * 这个方法就是去了解你追求的妹子
	 */
	int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
	
	int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
	
	int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
	
	int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}
我们先来看看BeanDefinitionRegistry

 

public interface BeanDefinitionRegistry extends AliasRegistry {
	/**
	 * 注册一个新的BeanDefinition,给你追的妹子起个名字
	 */
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws Exception;

	/**
	 * 删除这个BeanDefinition,如果你追她了,就删了她的电话号码吧
	 */
	void removeBeanDefinition(String beanName) throws Exception;

	/**
	 * 根据名字获得BeanDefinition,只要告诉你苍老师,你就知道是哪个妹子了。。。。。。。。。。
	 */
	BeanDefinition getBeanDefinition(String beanName) throws Exception;

	/**
	 * 是否包含这个BeanDefinition,小花是否在你追求名单里
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * 获得所有你追求的妹子名单,广撒网啊。。。。。。。
	 */
	String[] getBeanDefinitionNames();

	/**
	 * 获得你追求妹子的数量,看样子大家都很花心
	 */
	int getBeanDefinitionCount();

	/**
	 * 这个妹子是否已经是你女朋友了
	 */
	boolean isBeanNameInUse(String beanName);
}
看到 BeanDefinitionRegistry继承AliasRegister,它是什么呢,就是你给这个妹子起的外号
public interface AliasRegistry {
	
	/**
	 * 给你追的妹子起个外号,比如花花
	 */
	void registerAlias(String name, String alias);

	/**
	 * 在妹子的警告下,不得已去掉这个外号
	 */
	void removeAlias(String alias);

	/**
	 * 是否有这个外号
	 */
	boolean isAlias(String name);

	/**
	 * 获得你给这个妹子起的所有外号
	 */
	String[] getAliases(String name);
}
再来看看ResourceLoader,就像你有妹子的微信,你可以通过这个微信来了解她 

public interface ResourceLoader {
	
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
	
	/**
	 * 根据微信号,来获得妹子的信息
	 */
	Resource getResource(String location);
	
	ClassLoader getClassLoader();
}
下面是时候来看看具体怎么去了解这个妹子的。我们可以通过多种方式去了解这个妹子,微信,QQ,Spring兄也可以通过location,Resource去了解这个对象。

public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
	
	protected final Log logger = LogFactory.getLog(getClass());
	
	private final BeanDefinitionRegistry registry;

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

		
	}


	@Override
	public final BeanDefinitionRegistry getRegistry() {
		return this.registry;
	}

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

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

	/**
	 * 这个方法告诉我们如何去了解这个妹子的,最终调用了loadBeanDefinitions(resource),这个方法交给子类去实现
	 */
	@Override
	public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		Assert.notNull(resources, "Resource array must not be null");
		int counter = 0;
		for (Resource resource : resources) {
			counter += loadBeanDefinitions(resource);
		}
		return counter;
	}

	@Override
	public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}

	/**
	 * 获取资源加载器,这样就可以根据路径去加载资源了,就像你有妹子微信号,你就可以通过微信去了解这个妹子
	 * 最终调用了loadBeanDefinitions(resources)
	 */
	public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
		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 {
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources);
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				
				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.
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			
			return loadCount;
		}
	}

	@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;
	}
}
由上面的代码分析,所有的逻辑都在loadBeanDefinitions(Resource resource),这个方法在XmlBeanDefinitionReader类中实现,由于这个类比较复杂,将在下节详细讲解。




  




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值