字符串路径怎么查找XML资源
Spring中使用Xml配置时会使用ResourceLoader查找,官网文档里提到了很重要的一句:
NOTE:After you learn about Spring’s IoC container, you may want to know more about Spring’s
Resource
abstraction (as described in Resources), which provides a convenient mechanism for reading an InputStream from locations defined in a URI syntax. In particular,Resource
paths are used to construct applications contexts, as described in Application Contexts and Resource Paths.
这边我们先直接定位到最主要的一个实现类PathMatchingResourcePatternResolver,文章最后会解释为什么会是这个类以及它的作用。
classpath: 查找资源
我们通过spring-bean*.xml查找Xml配置文件的时候,流程如下:
也就是classLoader.getResource返回一个classpath路径,所以如果spring-bean.xml不存在该路径下那么就找不到了。
classpath* 带通配符查找资源
而我们通过classpath*:spring-bean*.xml来查找的时候,流程如下:
所以区别还是发生在PathMatchingResourcePatternResolver类的getResources方法内部
1 |
|
ClasspathXmlApplicationContext加载BeanDefinition会调用AbstractBeanDefinitionReader类的这个方法,方法内部会去获取当前的ResourceLoader:
AbstractBeanDefinitionReader#loadBeanDefinitions
那么当前的ResourceLoader到底是哪个呢?我们又要回到AbstractXmlApplicationContext去加载BeanDefinition的时候:XmlBeanDefinitionReader实例化后会把当前ApplicationContext设置为它的ResourceLoader
AbstractXmlApplicationContext#loadBeanDefinitions
为啥能设置呢?因为当前ApplicationContext的父类AbstractApplicationContext继承了DefaultResouceLoader。
1 | public abstract class AbstractApplicationContext extends DefaultResourceLoader{} |
且因为AbstractApplicationContext实现了ApplicationContext接口,ApplicationContext接口我们知道是继承自ResourcePatternResolver接口,从上篇文章的类图中我们可以一窥全貌。
所以从location获取资源就会调用AbstractApplicationContext的getResources方法:
1 | //--------------------------------------------------------------------- |
这边就很重要了,resourcePatternResolver就是在构造函数里实例化的
1 | /** |
到这里我们就看到了本文一开始提到的PathMatchingResourcePatternResolver,需要注意的是在实例化该ResourcePatternResolver的时候把当前ResourceLoader当作构造函数参数传了进去。ResourcePatternResolver最终返回一个Resource数组给到AbstractBeanDefinitionReader。