當用Spring的當用ClassPathXmlApplicationContext擷取應用上下文時。有兩種方法。
ApplicationContext context = new FileSystemXmlApplicationContext("c:/knight.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");
FileSystemXmlApplicationContext引用的是具體檔案系統的檔案路徑,而ClassPathXmlApplicationContext
在classpath找到xml檔案
剛開始使用的是用Maven所建構的web項目。目前項目位于G:/newtool/workspace/springmvc中
knight.xml是放在src/main/java中。如果放到了src/main/java/di中,構造參數應該傳入"di/knight.xml"
不然是找不到檔案的。
先看看maven建立的标準的目錄布局:
Introduction to the Standard Directory Layout
src/main/java/ 源檔案
src/main/resources 資源檔案
但是如果把knight.xml放到src/main/resources中時,并不需要構造參數應該傳入"src/main/resourcesres/knight.xml"
而是直接傳入"knight.xml"。
這裡就會意識到問題了,這樣看的話,我們要先找出classpath是哪裡。
String s[] = System.getProperty("java.class.path").split(";");
for (String string : s) {
System.out.println(string);
}
列印出來的包含G:/newtool/workspace/springmvc
還有就是bulid path還有classpath。
建議先看下兩個問題回答,我翻譯一些很好的解釋。
http://stackoverflow.com/questions/12893760/spring-cannot-find-bean-xml-configuration-file-when-it-does-exist
http://stackoverflow.com/questions/3529459/what-is-the-difference-between-class-path-and-build-path
先說classpath,classpath會告訴java編譯器還有運作時去找的編譯好的class。典型的是JAR檔案名稱還有目錄的一個序列。
Build path并不是java的術語,它用來建構應用,包含編譯該應用的所有源檔案和java庫。
IDE通過這個配置classpath和sourcepath。
是以,我run的時候,發現xml放在src/main/resources也好,放在src/main/java也好。
其實作在我們用慣了IDE之後忽略了一個問題。就是運作前還有進行一些操作的時候,
IDE都幫你重新建構項目了,是以放到這兩個目錄裡面。
将run的配置設定成運作前不自動build。然後手動删除
G:/newtool/workspace/springmvc目錄下的xml檔案,便會出現找不到xml的錯誤了。
前面我們是用了Maven建構,我們如果用Dynamic Web Project的時候。
classpath是在G:\newtool\workspace\SpringMVCweb\build\classes類似這樣的目錄下面的。
是以具體的還是在Eclipse這邊控制。
至于後面使用:
public class KnightMain {
public static void main(String[] args) throws Exception {
System.setProperty("java.class.path","G:/newtool/workspace;G:/newtool");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
String s[] = System.getProperty("java.class.path").split(";");
for (String string : s) {
System.out.println(string);
}
context.close();
}
}
為什麼沒有改變到classpath,xml還是正常加載到。
如果build是編譯的話,和最原始的javac又有什麼差別呢?
因為是從英語的思維去思考的,還有這些糾結幾個英文單詞的話,中文很難找到答案。是以這次自己是自己在Stackoverflow提了自己第一個英文問題。雖然英文寫的蹩腳。
http://stackoverflow.com/questions/39585055/whats-the-differences-between-the-build-function-of-eclipse-and-javac
最後的到了答案,好感謝這位德國朋友。
更改的JVM的classpath并不是目前運作的,是以現在正在編譯運作的還是原來的目錄。
是以xml還是正常找到。是以并影響到的是新的加載器,如果要想這樣,我們需要去用這個加載器去重新加載
整個spring的東西。确實這個真正相關的是Eclipse本身類加載器的一些配置上面了。追根到底的話。
不知道我為什麼會問這種這麼理論的問題,不過偶爾思考下問題也是好的。