spring 的 IOC 流程大致可以分为三步:1.资源定位;2.资源解析;3.注册 BeanDefinition
现在,来详细了解一下各个步骤
资源定位
资源定位的最后结果是封装了资源,在 spring 中为 Resource 类,其默认实现类为 FileUrlResource,封装了文件信息。
起始
资源定位的开始在 AbstractBeanDefinitionReader 文件,我们看一下加载资源的代码:
解析
在上面,我们看到定位的主要函数是 getResources,通过此函数可以将资源文件地址转化为 Resource 类,而此函数的主要实现方法在 PathMatchingResourcePatternResolver(如果对此类面生,可以看看 ClassPathXmlApplicationContext 构造方法,在那个构造方法中,调用父类创建了一个默认的 PathMatchingResourcePatternResolver)类中
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
return findPathMatchingResources(locationPattern);
}
else {
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(':') + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
return findPathMatchingResources(locationPattern);
}
else {
//我们的测试文件是直接写的路径,既没有classpath前缀也没有war等前缀,所以只执行到了这一步
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
封装
上一步,在默认的解析过后,进入了 getResource 方法(DefaultResourceLoader 类中),这个方法将开始进行封装操作,
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
for (ProtocolResolver protocolResolver : this.protocolResolvers) {
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
}
}
if (location.startsWith("/")) {
return getResourceByPath(location);
}
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
//在这里,将资源文件路径封装为URL,并进一步封装为 FileUrlResource
URL url = new URL(location);
return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
上面,最终将资源文件路径封装为了 FileUrlResource,整个定位流程结束。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于