博客
关于我
Class和ClassLoader的getResource方法对比
阅读量:700 次
发布时间:2019-03-17

本文共 3044 字,大约阅读时间需要 10 分钟。

最近在看Spring的源代码,里面有好多地方都用到了Class和ClassLoader类的getResource方法来加载资源文件。之前对这两个类的这个方法一知半解,概念也很模糊,这边做下整理,加深理解。


访问资源的主要方式

在Java中,通常可以通过以下方式来访问资源:

  • Class的getResource方法
  • ClassLoader的getResource方法
  • ClassLoader的getResources方法(获取批量资源)
  • ClassLoader的getSystemResource(静态方法)
  • 在使用中,Class可通过直接引用类的class属性而获得,或是通过实例的getClass()方法来获取。获取ClassLoader的方式则比较多,常见以下几种:

  • 调用Class的getClassLoader方法,如:getClass().getClassLoader()
  • 由当前线程获取ClassLoader:Thread.currentThread().getContextClassLoader()
  • 获取系统ClassLoader:ClassLoader.getSystemClassLoader()

  • Class.getResource 与 ClassLoader.getResource 的区别

    两者最大的区别,是从哪里开始寻找资源。

  • ClassLoader并不关心当前类的包名路径,它永远以classpath为基点来定位资源。需要注意的是在用ClassLoader加载资源时,路径不要以"/"开头,所有以"/"开头的路径都返回null;
  • Class.getResource如果资源名是绝对路径(以"/"开头),那么会以classpath为基准路径去加载资源。如果不以"/"开头,那么以这个类的Class文件所在的路径为基准路径去加载资源。

  • 正确使用getResource方法

    在实际开发过程中建议使用Class.getResource这个方法,但如果你想获取批量资源,那么就必须使用到ClassLoader的getResources()方法。

  • 避免使用Class.getResource("/")或ClassLoader.getResource("")。你应该传入一个确切的资源名,然后对输出结果作计算。

    • 比如,如果你确实想获取当前类是从哪个类路径起点上执行的,可以调用App.class.getResource(App.class.getSimpleName() + ".class")。
    • 如果所得结果不是jar协议的URL,说明class文件没有打包,将所得结果去除尾部的"test/App.class",即可获得test.App的类路径的起点;
    • 如果结果是jar协议的URL,去除尾部的"!/test/App.class",和前面的"jar:",即是test.App所在的jar文件的URL。
  • 如果要定位与某个类同一个包的资源,尽量使用那个类的getResource方法并使用相对路径。

    • 比如,获取与test.App.class同一个包下的App.js文件,应使用App.class.getResource("App.js")。
      -当然,事无绝对,用ClassLoader.getResource("test/App.js")也可以,这取决于你所面对的问题是什么。
  • 如果对ClassLoader不太了解,那就尽量使用Class的getResource方法。

  • 如果不理解或无法确定该传给Class.getResource方法的相对路径,那就以类路径的顶层包路径为参考起点,总是传给它以"/"开头的路径吧。

  • 不要假设你的调试环境就是最后的运行环境。你的代码可能不打包,也可能打包,你得考虑这些情况,不要埋坑。


  • 获取批量资源

    使用ClassLoader的getResources方法可以获取批量资源。

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();Enumeration
    resources = classLoader.getResources("META-INF/MANIFEST.MF");

    Spring的ResourceLoader

    在Spring框架中,ResourceLoader和ResourcePatternResolver接口封装了获取资源的方法,我们可以直接拿来使用。ResourceUtils这个类中提供了很多判断资源类型的工具方法,可以直接使用。

    //前面三种的写法效果是一样的,必须从classpath基准目录开始写精确的匹配路径ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.spring.xml");ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/beans.spring.xml");ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/beans.spring.xml");ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:/beans.spring.xml");

    ResourceLoader接口

    ResourcePatternResolver接口——重点

    给出一个例子:

    String txt = "";ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources("templates/layout/email.html");Resource resource = resources[0];//获取文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流InputStream stream = resource.getInputStream();StringBuilder buffer = new StringBuilder();byte[] bytes = new byte[1024];try {    for (int n; (n = stream.read(bytes)) != -1; ) {        buffer.append(new String(bytes, 0, n));    }} catch (IOException e) {    e.printStackTrace();}txt = buffer.toString();

    ResourceUtils

    ResourcePatternUtils

    转载地址:http://ucpez.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现Eulers TotientFunction欧拉函数算法(附完整源码)
    查看>>
    Objective-C实现EulersTotient欧拉方程算法(附完整源码)
    查看>>
    Objective-C实现eval函数功能(附完整源码)
    查看>>
    Objective-C实现even_tree偶数树算法(附完整源码)
    查看>>
    Objective-C实现Exceeding words超词(差距是ascii码的距离) 算法(附完整源码)
    查看>>
    Objective-C实现ExponentialSearch指数搜索算法(附完整源码)
    查看>>
    Objective-C实现extended euclidean algorithm扩展欧几里得算法(附完整源码)
    查看>>
    Objective-C实现ExtendedEuclidean扩展欧几里德GCD算法(附完整源码)
    查看>>
    Objective-C实现Factorial digit sum阶乘数字和算法(附完整源码)
    查看>>
    Objective-C实现factorial iterative阶乘迭代算法(附完整源码)
    查看>>
    Objective-C实现factorial recursive阶乘递归算法(附完整源码)
    查看>>
    Objective-C实现factorial阶乘算法(附完整源码)
    查看>>
    Objective-C实现Fast Powering算法(附完整源码)
    查看>>
    Objective-C实现fenwick tree芬威克树算法(附完整源码)
    查看>>
    Objective-C实现FenwickTree芬威克树算法(附完整源码)
    查看>>
    Objective-C实现fft2函数功能(附完整源码)
    查看>>
    Objective-C实现FFT快速傅立叶变换算法(附完整源码)
    查看>>
    Objective-C实现FFT算法(附完整源码)
    查看>>
    Objective-C实现fibonacci斐波那契算法(附完整源码)
    查看>>
    Objective-C实现FigurateNumber垛积数算法(附完整源码)
    查看>>