天天看點

由ClassPathXmlApplicationContext加載的classpath是哪裡引發的思考

當用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本身類加載器的一些配置上面了。追根到底的話。

不知道我為什麼會問這種這麼理論的問題,不過偶爾思考下問題也是好的。