前文
Spring源码解析之bean的创建与获取对springbean的加载有了一个初步的了解,接下来我们要做的就是对内部源码进行更深度的剖析!
资源解析的分析
Resource resource = new ClassPathResource("spring-config.xml");
我们对ClassPathResource
进行探究:
//这个构造方法调用了带有ClassLoader的构造方法,默认传了个null
public ClassPathResource(String path) {
this(path, (ClassLoader) null);
}
调用的具体构造:
/**
* 为使用{@code ClassLoader}创建一个新的{@code ClassPathResource}。
* 将删除一个前斜杠,因为ClassLoader资源访问*方法将不接受它。
*
* Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
* A leading slash will be removed, as the ClassLoader resource access
* methods will not accept it.
* @param path the absolute path within the classpath
* @param classLoader the class loader to load the resource with,
* or {@code null} for the thread context class loader
* @see ClassLoader#getResourceAsStream(String)
*/
public ClassPathResource(String path, @Nullable ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
String pathToUse = StringUtils.cleanPath(path);
//如果这个路径以斜杠开头,就把斜杠给去了
if (pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
this.path = pathToUse;
//如果传了classLoader,就把classLoader传给当前的classLoader,没传的话,就给个默认的
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
}
这里我对源码中注释的翻译使用的是idea的插件Translation
,翻译非常好用,安利一波~~
我们开始分析:
一、首先看他的cleanPath
方法,我们知道这是Spring讲五花八门的路径,通过各种校验转换成合法的路径!
二、去除斜杠,源码注释说的明明白白,ClassLoader资源访问方法将不接受它,这里的它就是指斜杠!
三、给path和classLoader赋值,这里面是个三元表达式,如果不为空的话,就传进当前的classLoader。我们再看看ClassUtils.getDefaultClassLoader()
@Nullable
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
//获取当前线程的上下文类加载器
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
//补救措施
if (cl == null) {
// No thread context class loader -> use class loader of this class.
//获取当前类加载器
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
//系统类加载器
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}
考虑的可谓不可不详细,如果没有传入ClassLoader,首先是获取当前线程的上下文类加载器,获取不到就获取当前类加载器,再不济就获取系统类加载器
到此资源加载的具体源码就分析完了,我们接着看DefaultListableBeanFactory
里的源码。
先看一下DefaultListableBeanFactory
类结构图:
我们看到DefaultListableBeanFactory
是最底层的,他的顶级父类是BeanFactory
,我们先看DefaultListableBeanFactory
的构造方法:
/**
* Create a new AbstractAutowireCapableBeanFactory.
* ignoreDependencyInterface:忽略给定接口的向动装配功能
*/
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
if (IN_NATIVE_IMAGE) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
ignoreDependencyInterface
/**
* Dependency interfaces to ignore on dependency check and autowire, as Set of
* Class objects. By default, only the BeanFactory interface is ignored.
*/
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
//忽略掉spring提供的但又不建议使用的依赖接口对象给忽略掉
public void ignoreDependencyInterface(Class<?> ifc) {
this.ignoredDependencyInterfaces.add(ifc);
}
到此为止,资源和bean工厂都准备好,但是这两者还没有关联!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/16385.html