spring容器实现详解一

  • 前面我们大概了解了spring容器的各个功能,可能有些迷糊,说实在的我也迷糊,不过不打紧,接下来来看看每个功能的具体的实现逻辑过程:
  • 在看之前我们先来看一段熟知的代码,代码如下:
 XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

简单的一行代码,大家都知道,从代码我们可以看到:

  1. new ClassPathResource()首先是去定位我们创建xml文件的所在位置.
  2. 然后就是相应的资源转化过程,将资源转化为Resource对象.
  3. 然后new XmlBeanFactory()这里需要一个resource对象.
  4. 加载对应的resource的文件等,至于用什么样的方法去加载resource文件,接下来看;
    这里只是简单的猜测,具体怎么样的,在这之前我们还需了解一个东西,就是spring是如何将我们的配置文件进行封装的,直击Resource类

原来该Resource是一个接口,我们也可以自定义资源类来实现自己资源文件的封装.
接下来看看spring对它的封装,代码如下:

''''''
/**
 * 资源类的抽象类
 */
public interface Resource extends InputStreamSource {

/**资源是否存在*/
boolean exists();

/**资源是否可读,这里首先需要判断该资源是否存在*/
default boolean isReadable() {
    return exists();
}

/**描述的是资源的一个句柄,默认是没有打开的*/
default boolean isOpen() {
    return false;
}

/**资源是否是一个file*/
default boolean isFile() {
    return false;
}

/**返回资源URL的句柄*/
URI getURI() throws IOException;

/**返回资源file的句柄*/
File getFile() throws IOException;
  /**返回资源文件的大小,这里是字节大小*/
long contentLength() throws IOException;

/**
 * Determine the last-modified timestamp for this resource.
 * @throws IOException if the resource cannot be resolved
 * (in the file system or as some other known physical resource type)
 */
/**资源的修改时间*/
long lastModified() throws IOException;

/**
 * Create a resource relative to this resource.
 * @param relativePath the relative path (relative to this resource)
 * @return the resource handle for the relative resource
 * @throws IOException if the relative resource cannot be determined
 */
/**创建一个相对于此资源文件路径的资源*/
Resource createRelative(String relativePath) throws IOException;

@Nullable
/**获取资源文件的name*/
String getFilename();
  /**返回此资源的描述内容*/
String getDescription();

}

上述是spring是如何封装资源的方法,我们可以看到Resource继承了InputStreamSource类,我们再来看看这个类到底是干了什么,代码如下:

public interface InputStreamSource {


/**获取资源的内容*/
InputStream getInputStream() throws IOException;

}
  • 该接口就一个方法,获取资源文件的内容,看完了spring是如何封装资源文件的.接下看spring是加载资源文件的
  • 接着上面的我们来看,当我们new ClassPathResource()时,都干了什么,代码如下:
public ClassPathResource(String path) {
    this(path, (ClassLoader) null);
}
  • 该方法是ClassPathResource类中方法,初始化一个ClassPathResoure类
  • 其中path为我们定义xml文件的绝对路径
  • 这里调用了内部的初始化的方法,只是需要多传了一个ClassLoader参数,代码如下:
/**
 *
 * @param path 资源的绝对路径
 * @param classLoader 当前类的加载器,允许为null
 */
public ClassPathResource(String path, @Nullable ClassLoader classLoader) {
    Assert.notNull(path, "Path must not be null");
    //路径转化,将Windows中的\\简化为\
    String pathToUse = StringUtils.cleanPath(path);
    //从/开始截取路径
    if (pathToUse.startsWith("/")) {
        pathToUse = pathToUse.substring(1);
    }
    //初始化,
    this.path = pathToUse;
    //获取默认的加载器
    this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
}
  • 上述两个方法是ClassPathResource.java中的初始化方法.
  • 首先来看一下ClassPathResource的自定义属性,代码如下:
private final String path;//当前我们配置文件的路径
@Nullable
private ClassLoader classLoader;//默认为null
@Nullable
private Class<?> clazz;//默认为null

我们可以看到它自己属性,一目了然,我们来看看是如何获取当前的加载器的过程,代码如下:

  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;
}
  • 代码简单明了,获取当前线程的上下文加载器,没拿到的话
  • 通过当前类的class来获取加载器,如果没拿到
  • 通过顶级加载器来获取
总结:
  1. 当我们new ClassPathResource()时,首先是我们配置文件的定位.
  2. 然后进行内部相应的抽象成一个Resource .
  3. 以及初始化一个默认的资源加载器

篇幅太长,下篇继续.......

转载于:https://www.jianshu.com/p/0bf4510519c7

猜你喜欢

转载自blog.csdn.net/weixin_33947521/article/details/91252276
今日推荐