博客
关于我
Java加载资源文件时的路径问题
阅读量:793 次
发布时间:2023-01-28

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

在学习Java类加载机制时,资源文件的路径问题经常会让人困惑。特别是在Tomcat加载Servlet以及处理资源文件时,了解如何有效地加载资源是至关重要的。资源文件可以是任何类型的文件,包括XML、properties、图片等。那么,如何正确地进行资源文件的加载呢?下面详细探讨一下两种主要的方法。

一、使用ClassLoader加载资源文件

在Java应用中,ClassLoader是一个非常重要的概念。它负责根据类路径(CLASSPATH)或JAR文件中的路径来加载类和资源。ClassLoader主要有三种类型:

  • 根类加载器(Bootstrap ClassLoader)

    这是由C++编写的稳定的类加载器。它负责加载JRE(Java Runtime Environment)中的一些核心类,如java.lang.Object和其他运行时所需的类。根类加载器负责加载的包路径为:BootstrapClassloader -> JRE/lib/rt.jar

  • 扩展类加载器(ExtClassLoader)

    这是由Java编写的扩展类加载器。它专门负责加载JRE中扩展包中的类。扩展类加载器负责加载的包路径为:ExtClassLoader -> JRE/lib/ext/*.jar

  • 应用类加载器(AppClassLoader)或系统类加载器

    这是负责加载用户应用中所依赖的类的加载器。通过调用ClassLoader.getSystemClassLoader()可以获取应用类加载器。它负责将CLASSPATH中的类加载到内存中。

  • 类加载器之间并非采用垂直的父子关系,而是一种组合关系。这意味着我们可以通过在类加载器的构造函数中传入父类加载器的实例来实现成层装载。例如,可以构造一个自定义的类加载器,将根类加载器或应用类加载器作为其父加载器。

    关于类加载器的继承关系

    类加载器的继承关系并不是传统的单向父子关系,而是通过将不同的加载器“串起来”,形成一种复合关系。这意味着,类加载器在装载类时,会依次委派给其子类加载器,直到某个类加载器能够实际装载该类。

    如何获取应用类加载器

    为了获取应用类加载器,我们可以调用ClassLoader.getSystemClassLoader()方法。它返回的是应用当前类加载器的实例,也就是系统类加载器。

    使用ClassLoader加载资源文件

    有一点需要注意的是,ClassLoader看待资源文件的方式与类的方式有明显区别。如果你想通过ClassLoader来加载资源文件,可以使用ClassLoader.getResource(String)方法。资源文件的路径有两种形式:

  • 相对路径:资源文件位于类路径的某个子目录下。此时,路径不需要以斜杠/开头。

    例如,假设资源文件names.ser位于Demo类所在的目录下的demo包中,路径应写成Demo.class.getResource("names.ser")
    但是如果需要加载外部文件,比如先前提到的demo/names.ser,必须使用以下方式。

  • 绝对路径:资源文件位于类路径之外,也就是说不位于任何包内。这时,你必须在路径前加上一个斜杠/,例如:URL url = getSystemClassLoader().getResource("/demo/names.ser");

  • 需要注意的是,忘记在类路径外的资源前加斜杜带将导致资源无法被找到。这个细节经常会让开发者困扰。

    关于Class.getResource方法

    Class提供了getResource()方法,它可以通过当前类的类加载器来获取资源文件。通过查看Class类源码,我们可以看出这个方法实际上会调用当前类的类加载器(调用getClassLoader())来获取资源文件。

    此外,Class类的resolveName()方法负责将资源文件的路径进行适当的转换。例如,假设你试图获取package reflects next.java中的资源文件res, 你需要注意路径如何处理。如果路径不以/开头,Class类会尝试将当前类的包路径添加到资源路径中。

    比如,假设你有一个类com.example.Demo1,它位于com.example包中。你可以通过以下方式加载com.example包下的资源文件names.ser

    URL resource = Demo1.class.getResource("names.ser");

    如果你想要加载位于类路径之外的结构化资源文件,可以通过在路径前加上斜杠:

    URL resource = Demo1.class.getResource("/com/example/names.ser");

    理解了这些实现机制后,就可以在实际应用中灵活处理资源文件的路径问题。无论是通过ClassLoader直接获取资源文件,还是通过Class.getResource方法进行间接调用,最终目标都是通过类加载器的机制来定位和加载所需的资源文件。

    通过以上分析,我们可以清晰地看到,Java中的形状加载机制是在类路径或JAR文件中寻找资源文件,最终由类加载器进行解释和加载。无论是内置的ClassLoader还是自定义的类加载器,掌握它们的工作原理都是解决资源加载问题的关键。

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

    你可能感兴趣的文章
    flask框架飞机订票管理系统(毕设源码+论文)
    查看>>
    flask框架餐饮管理系统毕设源码+论文
    查看>>
    flask框架高性能教学资源平台设计与实现(毕设源码+论文)
    查看>>
    flask框架高校助学及勤工俭学管理系统(毕设源码+论文)
    查看>>
    flask框架高校图书管理系统设计与实现(毕设源码+论文)
    查看>>
    flask框架高校招生预报管理系统(毕设源码+论文)
    查看>>
    flask框架高校教师个人数字档案(毕设源码+论文)
    查看>>
    flask框架高校毕业生选题系统(毕设源码+论文)
    查看>>
    flask框架高校竞赛信息管理系统(毕设源码+论文)
    查看>>
    flask框架魔方教学网站毕设源码+论文
    查看>>
    Flask解决跨域访问问题(Access to XMLHttpRequest at ‘http://127.0.0.1:500been blocked by CORS policy: No ‘Acc)
    查看>>
    Flatterer: 快速JSON转换工具使用指南
    查看>>
    Flex / PHP Security Basics - Part One
    查看>>
    FLEX 4 :选择本地文件编辑
    查看>>
    Flex 与 spring mvc 整合 BlazeDB
    查看>>
    flex 动态创建组件之容器自适应大小
    查看>>
    java.net.ConnectException: no available server
    查看>>
    java 记事本程序_Java记事本程序Notebook
    查看>>
    Java 访问Kerberos认证的HDFS
    查看>>
    java 重载、重写、重构的区别
    查看>>