理解classpath
一、什么是classpath
| 类路径的类型 | 描述 |
| "." | 表示当前目录,即执行java命令启动应用的目录。如果我们不显式的设置任何类路径,则默认它包含一个多当前目录;但如果显式设置了类路径,并且设置的路径不包含当前目录的话,则类路径就不包含当前目录了 |
| 扩展目录 | (1)扩展目录可以是包含class文件的基目录,比如“/home/user/classdir”,该目录作为类路径,其下的内容就开始是包路径目录。
![]() (2)扩展目录也可以是一些其他的文件目录,不过jvm并不能从中找到class文件,该目录用于存放一些文件以供查找使用。
|
| jar文件 | 比如“/home/user/lib/Foo.jar”,该jar文件的完整路径也能作为类路径。当然,从javaSE6开始,可以通过通配符“*”一次指定多个jar,例如“/home/user/lib/*” |
| 运行时库文件,rt.jar,jre/lib,jre/lib/ext | 这些不用手动指定,它们默认包含在类路径中 |
二、如何设置classpath
1 #方式1
2 java -classpath 具体的类路径
3 #-classpath也可以简写成-cp
4 java -cp 具体的类路径
5 #示例
6 java -classpath .:/home/user/classdir:/home/user/lib/*
7
8 #方式2(不推荐使用),使用CLASSPATH环境变量,JVM启动时会去查找CLASSPATH这个环境变量
9 export CLASSPATH=".:/home/user/classdir:/home/user/lib/*"
需要注意的是,某些情况下不需要我们设置classpath,比如在tomcat或者jetty中启动应用,亦或者是通过springboot可执行jar启动应用时,我们都未设置classpath,但这并不代表不用设置,而是框架或者容器替我们做好了这个事。
三、"classpath:"与"classpath*:"
3.1.不包含通配符的路径
| 查找规则 | 进一步说明 | |
| classpath: | (1)既可以查找类路径中扩展目录下的资源,也可以查找类路径中jar包内的资源。 (2)查找顺序是按照类路径定义的顺序逐个查找扩展目录或jar包(并不是网上说的先去查找扩展目录再查找jar包),并返回查找到的第一个资源。 |
(1)返回的Resource都是ClasspathResource。 (2)如果资源位于扩展目录中,从ClasspathResource中获取到的是BufferedInputStream;如果位于jar包中,获取到的则是JarURLInputStream。 |
| classpath*: | (1)既可以查找类路径中扩展目录下的资源,也可以查找类路径中jar包内的资源。 (2)返回查找到的所有的匹配文件资源,因此可以不考虑查找顺序。 |
(1)返回的Resource都是URLResource。 (2)如果资源位于扩展目录中,从URLResource获取到的是BufferedInputStream;如果位于jar包中,获取到的则是JarURLInputStream。 |
3.2.包含通配符的路径
| 根目录类型 | 查找规则 | 进一步说明 | |
| classpath: | 空目录,即"" | (1)只在类路径中的扩展目录下查找资源,无法在类路径中的jar内查找。 (2)查找过程比较复杂:假设定义了3个类路径,分别是扩展目录"dir1"和"dir2",以及通配符jar包"dir3/*",它们的顺序可以是任意的,如"dir1:dir2:dir3/*"或者"dir3/*:dir2:dir1"。step1.首先过滤掉类路径中的jar包,剩下的扩展目录保持定义顺序不变;step2.按照类路径定义的顺序逐个查找扩展目录,如果在某个扩展目录下查找到匹配的资源文件,则将查找范围锁定在该扩展目录下,并返回该扩展目录下所有匹配的资源文件。 |
(1)返回的Resource都是FileSystemResource,从中获取FileInputStream。 (2)实际上,之所以无法去jar包中查找,是因为ClassLoader的getResources方法在传入""时,只能返回扩展目录资源。 |
| 包含了有效路径的目录 | (1)既可以查找类路径中扩展目录下的资源,也可以查找类路径中jar包内的资源。 (2)查找过程比较复杂:假设定义了3个类路径,分别是扩展目录"dir1"和"dir2",以及通配符jar包"dir3/*",它们的顺序可以是任意的,如"dir1:dir2:dir3/*"或者"dir3/*:dir2:dir1"。step1.直接按照类路径定义的顺序逐个查找扩展目录或jar包,如果查找到包含“根目录”的某个类路径,则将查找范围锁定在此类路径下,并返回此类路径下所有匹配的资源文件,如果没有匹配的就返回空。 |
(1)如果资源位于扩展目录中,返回的Resource是FileSystemResource,从中获取到FileInputStream。 (2)如果资源位于jar包中,返回的Resource是ClasspathResource,从中获取到JarURLInputStream。 |
|
| classpath*: | 空目录,即"" | (1)既可以查找类路径中扩展目录下的资源,也可以查找类路径中jar包内的资源。 (2)返回查找到的所有的匹配文件资源,因此可以不考虑查找顺序。 |
(1)如果资源位于扩展目录中,返回的Resource是FileSystemResource,从中获取到FileInputStream。 (2)如果资源位于jar包中,返回的Resource是URLResource,从中获取到JarURLInputStream。 |
| 包含了有效路径的目录 |
3.3.总结查找规则
- "classpath*:":总是能在类路径的扩展目录和jar包中查找,并且返回所有的匹配资源。
- "classpath:"(不含通配符):总是能按照类路径定义的顺序逐个查找扩展目录或jar包,并返回第一个匹配的资源。
- "classpath:"(含通配符):首先判断根目录是否为"",来决定查找的类路径范围是否需要过滤掉jar包。在处理后的类路径中按照定义的顺序逐一查找,直到查找出第一个匹配的资源文件,同时锁定该资源文件所在的类路径。之后查找并返回该锁定的类路径中所有匹配的资源文件。
四、框架和容器中的classpath
4.1.web容器的classpath
- WEB-INF/classes:存放src目录java文件编译之后的class文件、xml、properties等资源配置文件。
- WEB-INF/lib:存放依赖库。
4.2.springboot的classpath
在springboot项目中,我们启动可执行jar时一般不指定classpath,那么springboot的classpath如何指定的呢?我们先来看一个典型的springboot项目打包结构:
在META-INF中存在清单文件MANIFEST.MF,打开该文件查看里面的内容,我们找到main-class属性指定的并非是我们编写的应用启动类ServiceFeignApplication,而是org.springframework.boot.loader.JarLauncher。


- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
4.3.自定义打包的classpath

理解classpath的更多相关文章
- JAVA classpath jar问题[zz]
classpath问题可以说是所有初学者头疼的问题,偶也一样. 1) classpath的作用: 它的作用就事让java找到你所要执行,或你拥有的类. 2) classpath的设置: 设置cla ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- java与java学习路线
JAVA学习路线图 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面 ...
- 20155321 2016-2017-2 《Java程序设计》第一周学习总结
学习目标 [√]了解Java基础知识 [√]了解JVM.JRE与JDK,并下载.安装.测试JDK [√]了解PATH.CLASSPATH.SOURCEPATH的作用并会设置 [√]初步使用IDE(推荐 ...
- 20155337祁家伟 2016-2017-2 《Java程序设计》第2周学习总结
20155337 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 这周我学习了从JDK到IDE的学习内容,简单来说分为以下几个部分 使用命令行和IDE两种方式 ...
- 手动编译java的package问题,及演示继承的基本实现
不用IDE,而直接用命令编译JAVA包,仔细看了下,作一个记录. 以下的URL值得收藏. http://www.aiuxian.com/article/p-2115485.html http://ww ...
- 一文彻底搞懂Java中的环境变量
一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...
- 理解根目录,classpath, getClass().getResourceAsStream和getClass().getClassLoader().getResourceAsStream的区别
一: 理解根目录 <value>classpath*:/application.properties</value> <value>classpath:/appli ...
- path、classpath理解
path.classpath最常见的场景:环境变量配置 path环境变量:设置path的作用是让操作系统可以找到JDK命令(指定了JDK命令搜索路径):path环境变量原来Windows里面就有,只需 ...
随机推荐
- 微信小程序全局数据globalData的使用问题
如果在A页面设置全局属性,但在B页面无法使用的话,可能是这个问题: app.js globalData: { helpPage:0, }, A页面 A(e) { getApp().globalData ...
- Mysql生成UUID的SQL语句
大写的UUID: SELECT UPPER(UUID()); 小写的UUID: SELECT LOWER(UUID()); SELECT UUID(); 去掉横杠的UUID: SELECT REPLA ...
- js清空input file的值
原文:js清空input file的值 在做选择本地图片上传的功能时遇到一个问题,第一次点file按钮选择图片完成会触发onchange事件,获取文件后动态在界面上创建img标签展示,但把创建的img ...
- 【js】--获取开始时间 和 截止时间中间的所有时间
1.工具函数 将[中国标准时间] 转换成 [年月日 时分秒] /* * timeStamp: 标准时间 例: 'Tue Sep 22 2020 00:00:00 GMT+0800 (中国标准时间)' ...
- Java中的比较器(排序)
"顺序"在任何一个领域里都是非常重要的一个概念,程序也不例外.不同的执行顺序,能对你的执行结果产生直接影响. 既然涉及到顺序,那就要求排序.所以本文讨论的就是排序中使用到的比较器C ...
- new和delete关键字
new关键字创建出来的对象位于什么地方?很明显嘛,new关键字创建出来的对象一定位于堆空间,这种说法一定正确吗?本篇博客帮你揭开其神秘的面纱. 被忽略的事实new/delete的本质是C++预定义的操 ...
- 关于int和Integer缓存(二):修改缓存大小
续上文: java中的基础数据类型长度是否取决于操作系统? 在一些语言中,数据类型的长度是和操作系统有关系的,比如c和c++: 但是在java中,java的基础类型长度都是固定的,都是4个字节.因为j ...
- ProjectEuler 006题
题目: The sum of the squares of the first ten natural numbers is, 12 + 22 + ... + 102 = 385 The square ...
- 4种Golang并发操作中常见的死锁情形
摘要:什么是死锁,在Go的协程里面死锁通常就是永久阻塞了,你拿着我的东西,要我先给你然后再给我,我拿着你的东西又让你先给我,不然就不给你.我俩都这么想,这事就解决不了了. 本文分享自华为云社区< ...
- Java实现小程序微信支付
小程序支付流程交互图: 进入小程序,下单,请求下单支付,调用小程序登录API来获取Openid,生成商户订单 // pages/pay/pay.js var app = getApp(); Page( ...
