Web基础之classpath与classpath*

来源:互联网 发布:随机抽名字软件 编辑:程序博客网 时间:2024/05/03 21:00

前言

在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操作待补充

0 0
原创粉丝点击