Java web项目的classpath和classpath*的区别,*和**的区别及如何查找Java资源文件路径

这里的项目都是Web项目才有classpath:

web项目中的src路径下的文件在编译后会放到WEB-INF/classess路径下,默认的classpath路径就是WEB-INF/classess路径,直接放到WEB-INF下的话,是不在classpath下的。用ClassPathXmlApplicationContext是获取不到的。

如果是单元测试的话,可以在启动或者运行的时候指定classpath路径。

用maven构建web项目的时候,resource目录就是默认的classpath  
classPath即为java文件编译之后的class文件的编译目录一般为WEB-INF/classess,src下的xml在编译时也会复制到classPath下. 
ApplicationContext ctx = new ClassPathXmlApplicationContext("xxxx.xml");  //读取classPath下的spring.xml配置文件  
ApplicationContext ctx = new FileSystemXmlApplicationContext("WebRoot/WEB-INF/xxxx.xml");   //读取WEB-INF 下的spring.xml文件  

首先 classpath是指 WEB-INF文件夹下的classes目录 

解释classes含义:   
1.存放各种资源配置文件 eg.init.properties log4j.properties struts.xml   
2.存放模板文件 eg.actionerror.ftl   
3.存放class文件 对应的是项目开发时的src目录编译文件   
总结:这是一个定位资源的入口   

classpath 和 classpath* 区别: 
classpath:只会到你的class路径中查找找文件; 

classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 

<param-value>classpath:applicationContext-*.xml</param-value>  
或者引用其子目录下的文件,如 
<param-value>classpath:context/conf/controller.xml</param-value>  
classpath*的使用:当项目中有多个classpath路径,并同时加载多个classpath路径下(此种情况多数不会遇到)的文件,*就发挥了作用,如果不加*,则表示仅仅加载第一个classpath路径,代码片段: 
<param-value>classpath*:context/conf/controller*.xml</param-value>  

另外: 
"**/" 表示的是任意目录; 
"**/applicationContext-*.xml"  表示任意目录下的以"applicationContext-"开头的XML文件。  
程序部署到tomcat后,src目录下的配置文件会和class文件一样,自动copy到应用的 WEB-INF/classes目录下 
classpath:与classpath*:的区别在于, 
前者只会从第一个classpath中加载,而后者会从所有的classpath中加载 。 如果要加载的资源, 不在当前ClassLoader的路径里,那么用classpath:前缀是找不到的, 这种情况下就需要使用classpath*:前缀 。在多个classpath中存在同名资源,都需要加载, 那么用classpath:只会加载第一个,这种情况下也需要用classpath*:前缀 

注意: 

用classpath*:需要遍历所有的classpath,所以加载速度是很慢的,因此,在规划的时候,应该尽可能规划好资源文件所在的路径,尽量避免使用 classpath* 。

 下面说 java classpath如何指定一个目录及java资源文件的路径查找问题

一、资源文件的路径查找

当我们自己的程序需要处理配置文件时(比如xml文件或properties文件),通常会遇到两个问题:

  (1)我的配置文件应该放在哪里?

  (2)怎么我的配置文件找不到了?

  在了解了Java加载资源文件的机制后,以上这两个问题便迎刃而解了。

对于第一个问题,答案是:请将你的资源文件放在classpath里,如果资源文件在jar中,请将该jar文件也加到classpath里面。

二、依赖类的路径设置

通过java -classpath参数,我们可以指定java程序去哪里寻找需要执行或依赖的类

jar包需要在-classpath中指定,或者可以通过通配符来使用,class文件或者其他文件可以指定路径

对于web项目或者jar项目,如果想要将配置文件移到固定的目录下,则需要通过classpath指定该目录,注意指定到文件所在的目录即可,后面不能再添加'/',或者'/*',这些画蛇添足的事情:命令如下所示:/opt/test/filedir放的是配置文件,/opt/web/web-project/* 项目所打的包,/opt/web/web-project/dependency/* 项目所依赖的包

java -classpath /opt/test/filedir:/opt/web/web-project/*:/opt/web/web-project/dependency/* com.test.Application

在执行java程序的时候,如果程序中引用了其他的class文件或者jar包,通常我们都要通过 classpath参数来指定这些需要依赖的文件,比如

java -classpath "lib/Hutuseng.jar" my.package.TestClass
如果不指定classpath的话,就会报错,说找不到相应的class,比如NoClassDefFoundError and java.lang.ClassNotFoundException 

如果需要依赖的jar包很多的话,那么classpath就会写的很长,比如
java -classpath .;.\lib\lucene-core-5.2.1.jar;.\lib\IKAnalyzer2012_V5.jar;.\lib\lucene-analyzers-smartcn-5.2.1.jar;.\lib\lucene-queryparser-5.2.1.jar;.\lib\mysql-connector-java-5.1.26-bin.jar com.hutuseng.IndexBuilder

当然,我们可以设置CLASSPATH环境变量,只不过环境变量是系统级的,没法对不同的应用分别设置,在实际的应用中很少这么用。
也可以一次性写个批处理文件,以后就直接执行这个文件,以前我也是一直这么干的。其实心中也一直有这个疑惑,到底能不能指定一个目录或者使用文件通配符的方式(*.jar),java程序执行的时候,自动到这个目录中搜索呢?

google了一下,发现在java6以及后续的版本中,提供了对通配符的支持。

如果您的jdk还是老版本,那么就没法用通配符了,就只能一个一个写了,或者如果是在unix系统中,可以用shell的功能把路径下的所有jar文件拼接起来,
比如 java -classpath $(echo libs/*.jar | tr ' ' ':') Test

那么java6以后的通配符怎么用呢?
我们看看这个例子
java -classpath "./libs/*" Test
这里的*是指libs目录里的所有jar文件,不能这么写 java -classpath "./libs/*.jar" Test

如果libs目录中既有jar文件又有class文件,我们都想引用,那么就需要这么写
java -classpath "./libs/*;./libs/" Test
注意:windows系统里的分隔符是;  Unix系统的分隔符是:

另外需要注意的就是 libs/* 不包含libs目录下的子目录里的 jar文件,比如 libs/folder1/A.jar 
如果想包含子目录,那就需要都明确指出,比如
java -cp "./libs/*;./libs/folder1/*" Test

三、maven中打包依赖的路径配置

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <excludes>
            <exclude>*.properties</exclude>
            <exclude>*.xml</exclude>
            <exclude>*.sh</exclude>
        </excludes>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib</classpathPrefix>
                <mainClass>com.hhht.riskcontrol.thirdparty.tongdun.LoginServer</mainClass>
            </manifest>
            <manifestEntries>
                <Class-Path>conf/</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

猜你喜欢

转载自blog.csdn.net/quliuwuyiz/article/details/79658951