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操作待补充
- Web基础之classpath与classpath*
- web.xml 配置中classpath: 与classpath*:
- classpath:与classpath*:分析
- Classpath基础
- Classpath基础
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 中 classpath*:与classpath:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中“classpath” 与“classpath*”的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- web.xml 配置中classpath: 与classpath*:的区别
- 欢迎使用CSDN-markdown编辑器
- 抽象类可以继承实体类吗?
- 弧形ProgressBar、SeekBar
- Java重修之路(十)面向对象之多态详解,Object类,内部类,匿名内部类详解
- 文章标题
- Web基础之classpath与classpath*
- 数据结构(四)---栈的顺序存储的实现---java版
- 郝斌的C语言基础 041
- 一个开始
- 用有库的语言来实现排序算法
- Android开发艺术探索总结之View篇
- CTS 认证 低内存优化引起fail项验证方法
- 你该知道的RPC原理
- Android基础篇之补间动画(Tween)