通过前面的学习,我们已经获得对象的位置信息(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类中实现,由于这个类比较复杂,将在下节详细讲解。