Class类的getResource方法与getResourceAsStream方法

这两个方法,接收一个资源的路径参数name,返回一个代表资源的url或输入流。与linux中的文件定位类似,若name以“/”开头,此时将name视为绝对路径,后续classLoader会尝试以每一个classpath为根,以name为后续路径去寻找资源;若name不以“/”开头,则name为相对路径,相对于当前class对象对应类所在的包,在这个包路径的基础上以name为后续路径寻找资源。

1.getResource方法:

    public java.net.URL getResource(String name) {
        //转换name为绝对路径
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResource(name);
        }
        //实际上委托给classLoader
        return cl.getResource(name);
    }

resolveName方法:

这个方法对name参数的格式进行转换,假如当前class对象所在包为com.test,则对于相对路径“a/b/c”,返回“com/test/a/b/c”;对于绝对路径"/a/b/c",返回"a/b/c"。

    private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class<?> c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/')
                    +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

name被转换后传给ClassLoader类的getResource方法:

类似于双亲委派机制,每个classLoader首先委派给父类classLoader去定位name对应的资源,父类classLoader定位不到时,则自己去定位,最终相当于在每一个的classpath中尝试以name为路径定位资源

    public URL getResource(String name) {
        URL url;
        if (parent != null) {
            url = parent.getResource(name);
        } else {
            url = getBootstrapResource(name);
        }
        if (url == null) {
            url = findResource(name);
        }
        return url;
    }

2.getResourceAsStream方法:

类似于getResource,转换name后委托给classLoader的getResourceAsStream方法

     public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

ClassLoader类的getResourceAsStream方法:

    public InputStream getResourceAsStream(String name) {
        //简单的调用该类的getResource方法,上文已经提到过
        URL url = getResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_37720278/article/details/83931354