1. 程式人生 > >Java web專案的classpath和classpath*的區別,*和**的區別及如何查詢Java資原始檔路徑

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>