Web基础之classpath与classpath*

本文探讨了在Java Web开发中classpath与classpath*的区别,通过Spring和log4j框架的具体配置实例,深入分析了这两种路径标识的工作原理,并揭示了它们在加载资源方面的实际行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在web开发中经常碰到classpath与classpath* 的概念,具体的含义从网络中能了解个大概,这篇文章将从代码中来认识它们

正文

java web开发,在web.xml中经常使用到classpath与classpath*,如下例子
spring的配置文件在web.xml的配置

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:config/spring-*.xml,classpath*:config/dispatcher-servlet.xml</param-value>
    </context-param>

log4j的配置文件在web.xml的配置

<context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:config/log4j.properties</param-value>
    </context-param>

网上说这两者的区别是classpath只加载当前项目的classpath路径下的资源,而classpath*在加载当前项目的classpath路径下的资源同时也会加载到jar的资源。这个结论是从哪里得出来的,是官方的文档还是从源码中得知的? 是否真的如上面说的那样呢?
从上面的两个配置可以看到,classpath与classpath*是配置在xml中的,也就是说当spring框架或者log4j框架在web.xml的监听器加载初始化的时候需要读取这两个路径。我从两者框架源码中发现无论是classpath还是classpath* 只不过是一个标识而已(ignore:如同将复杂的业务,抽象成面向对象,需要很多很多的变量来表现),两者框架都会做一步以下的操作

String resourcePath = "classpath:/config/log4j.properties" ;
        if(resourcePath.startsWith("classpath")) {
            //使用classloader加载,在web中就是tomcat提供的WebappClassLoader加载器
            //它默认就会去WEB-INF/classes 和WEB-INF/lib这两个目录下加载
            //所以可以加载到WEB-INF/classes下的资源,也可以加载到WEB-INF/lib中jar的资源
            //使用加载器加载可以得到URL,然后使用URL.openConnection打开流操作
        }else {
            //如果不是classpath开头,那么认为资源在本地工程
            //如果是log4j的话,使用servletContext.getRealPath();
            //得到在当前项目的资源路径并用new URL(path)包装,最后采用URL.openConnection打开流操作
            //如果是spring,无论是classpath还是/WEB-INF/..这样的配置都会用上面的WebappClassLoader加载,加载器得到的URL openConnection来打开流操作
        }

从上面的代码以及注释可以知道,加载资源可以用加载器(不同加载器有不同的加载目录,这里是tomcat提供的webappclassloader)加载默认目录的资源,也可以是指明一条本地文件系统的路径,然后用new URL(localFileSystemPath) 来加载资源(如何获取资源所在的本地文件系统的完整路径,这里方法很多,后面文章再做总结)

从上面的分析可以看出classpath与classpath* 还真不能用资源是否在jar包下来区分,不同的框架有着不同的处理,可能一些框架还不认你classpath或者classpath*呢。比如下面代码在classpath后面加了一个*号导致异常,因为log4j在解析的逻辑代码中不支持classpath*仅仅是str.startWith("classpath")来区分实现不同逻辑而已

错误的log4j资源路径配置

<context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath*:config/log4j.properties</param-value>
    </context-param>

加载jar包资源

加载jar的资源其实没那么神秘,使用webappclassloader就可以加载到WEB-INF/lib下的jar资源了,再用jar包的api操作

private void deal() {
        ClassLoader loader =  Thread.currentThread().getContextClassLoader();//使用tomcat启动时存放到线程中的加载器
        if(loader == null) {
            loader = Log4jController.class.getClassLoader(); //使用加载当前类的加载器
        }
         try {
            Enumeration<URL> urls = loader.getResources("/config");
            while(urls.hasMoreElements()) {
                URL url = urls.nextElement();
                System.out.println(url);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

下载的jar操作待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值