日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

classpath: spring 中的查找方式

發布時間:2023/12/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 classpath: spring 中的查找方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring可以通過指定classpath*:與classpath:前綴加路徑的方式從classpath加載文件,如bean的定義文件.classpath*:的出現是為了從多個jar文件中加載相同的文件.classpath:只能加載找到的第一個文件.

比如 resource1.jar中的package 'com.test.rs' 有一個 'jarAppcontext.xml' 文件,內容如下:

<bean name="ProcessorImplA" class="com.test.spring.di.ProcessorImplA" />

resource2.jar中的package 'com.test.rs' 也有一個 'jarAppcontext.xml' 文件,內容如下:

<bean id="ProcessorImplB" class="com.test.spring.di.ProcessorImplB" />

通過使用下面的代碼則可以將兩個jar包中的文件都加載進來

ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath*:com/test/rs/jarAppcontext.xml");

而如果寫成下面的代碼,就只能找到其中的一個xml文件(順序取決于jar包的加載順序)

ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/test/rs/jarAppcontext.xml");

classpath*:的使用是為了多個component(最終發布成不同的jar包)并行開發,各自的bean定義文件按照一定的規則:package+filename,而使用這些component的調用者可以把這些文件都加載進來.

classpath*:的加載使用了classloader的 getResources() 方法,如果是在不同的J2EE服務器上運行,由于應用服務器提供自己的classloader實現,它們在處理jar文件時的行為也許會有所不同。 要測試classpath*: 是否有效,可以用classloader從classpath中的jar文件里加載文件來進行測試:getClass().getClassLoader().getResources("<someFileInsideTheJar>")。(上面的例子是在sun的jre中運行的狀態)

?從Spring的源碼,在PathMatchingResourcePatternResolver類中,我們可以更清楚的了解其對的處理:如果是以classpath*開頭,它會遍歷classpath.

[java] view plaincopy
  • protected?Resource[]?findAllClassPathResources(String?location)?throws?IOException?{??
  • ????String?path?=?location;??
  • ????if?(path.startsWith("/"))?{??
  • ????????path?=?path.substring(1);??
  • ????}??
  • ????Enumeration?resourceUrls?=?getClassLoader().getResources(path);??
  • ????Set<Resource>?result?=?new?LinkedHashSet<Resource>(16);??
  • ????while?(resourceUrls.hasMoreElements())?{??
  • ????????URL?url?=?(URL)?resourceUrls.nextElement();??
  • ????????result.add(convertClassLoaderURL(url));??
  • ????}??
  • ????return?result.toArray(new?Resource[result.size()]);??
  • }??
  • http://blog.csdn.net/kkdelta/article/details/5560210,簡介了在JAVA里遍歷classpath中讀取找到的所有符合名稱的文件.

    另外在加載resource的時候,其他前綴的意義如下表所示:注意classpath*只能用與指定配置文件的路徑,不能用在用于 getResource的參數.如 appContext.getResource("classpath*:conf/bfactoryCtx.xml")會異常的.

    前綴例子說明

    classpath:

    classpath:com/myapp/config.xml

    從classpath中加載。

    file:

    file:/data/config.xml

    作為 URL 從文件系統中加載。

    http:

    http://myserver/logo.png

    作為 URL 加載。

    (none)

    /data/config.xml

    根據 ApplicationContext 進行判斷。

    從Spring的源碼可以看出原因:如果是classpath:開頭,從classpath加載,否則嘗試URL,如果失敗,調用 getResourceByPath

    [java] view plaincopy
  • public?Resource?getResource(String?location)?{??
  • ????????Assert.notNull(location,?"Location?must?not?be?null");??
  • ????????if?(location.startsWith(CLASSPATH_URL_PREFIX))?{??
  • ????????????return?new?ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()),?getClassLoader());??
  • ????????}??
  • ????????else?{??
  • ????????????try?{??
  • ????????????????//?Try?to?parse?the?location?as?a?URL...??
  • ????????????????URL?url?=?new?URL(location);??
  • ????????????????return?new?UrlResource(url);??
  • ????????????}??
  • ????????????catch?(MalformedURLException?ex)?{??
  • ????????????????//?No?URL?->?resolve?as?resource?path.??
  • ????????????????return?getResourceByPath(location);??
  • ????????????}??
  • ????????}??
  • ????}??

  • getResourceByPath會被不同ApplicationContext 實現覆蓋.

    如 GenericWebApplicationContext覆蓋為如下:

    [java] view plaincopy
  • protected?Resource?getResourceByPath(String?path)?{??
  • ????????return?new?ServletContextResource(this.servletContext,?path);??
  • ????}??
  • ??
  • 如?FileSystemXmlApplicationContext覆蓋為如下:??
  • ??
  • protected?Resource?getResourceByPath(String?path)?{??
  • ????????if?(path?!=?null?&&?path.startsWith("/"))?{??
  • ????????????path?=?path.substring(1);??
  • ????????}??
  • ????????return?new?FileSystemResource(path);??
  • ????}??
  • 最終從文件加載的時候仍然是JAVA中常見的讀取文件的方法:

    如ClassPathResource得到inputstream的方法是利用class loader.

    [java] view plaincopy
  • public?InputStream?getInputStream()?throws?IOException?{??
  • ????InputStream?is;??
  • ????if?(this.clazz?!=?null)?{??
  • ????????is?=?this.clazz.getResourceAsStream(this.path);??
  • ????}??
  • 如FileSystemResource得到inputstream的方法是利用FileInputStream.

    ??? public InputStream getInputStream() throws IOException {
    ?? ??? ?return new FileInputStream(this.file);
    ?? ?}

    如ServletContextResource得到inputstream的方法是利用servletContext.getResourceAsStream.

    [java] view plaincopy
  • public?InputStream?getInputStream()?throws?IOException?{??
  • ????InputStream?is?=?this.servletContext.getResourceAsStream(this.path);??
  • ????if?(is?==?null)?{??
  • ????????throw?new?FileNotFoundException("Could?not?open?"?+?getDescription());??
  • ????}??
  • ????return?is;??
  • }?
  • 轉載于:https://www.cnblogs.com/1995hxt/p/5800257.html

    總結

    以上是生活随笔為你收集整理的classpath: spring 中的查找方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。