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>