天天看點

Spring中的資源加載政策

文/杜琪(簡書作者)

原文連結:http://www.jianshu.com/p/9cdd6d750216

著作權歸作者所有,轉載請聯系作者獲得授權,并标注“簡書作者”。

本文是閱讀《spring揭秘》的筆記

資源表示:resourcespring架構内部使用org.springframework.core.io.resouce接口作為所有資源的抽象和通路接口。

//resource接口的定義

public interface resource extends inputstreamsource {

 boolean exists();

 boolean isreadable();

 boolean isopen();

 url geturl() throws ioexception;

 uri geturi() throws ioexception;

 file getfile() throws ioexception;

 long contentlength() throws ioexception;

 long lastmodified() throws ioexception;

 resource createrelative(string var1) throws ioexception;

 string getfilename();

 string getdescription();

}

resouce接口可以根據資源的不同類型,或者資源位置的不同,給出對應的具體實作,spring架構提供了一些實作類:

bytearrayresource。将位元組數組作為資源進行封裝,如果通過inputstream形式通路該類型的資源,該實作會根據位元組數組的資料,構造出對應的bytearrayinputstream并傳回。

classpathresource。從java應用的classpath中加載具體的資源并封裝,可以使用指定的類加載器或者給定的類進行資源加載。

filesystemresource。可以以檔案或者url的形式對該資源進行通路,隻要能跟file打的交道,基本上跟filesystemresource也可以。

urlresource。通過java.net.url進行具體資源查找定位的實作類。

inputstreamresource。将給定的inputstream視為一種資源的resource實作類,比較少用。

資源加載:resourceloader在spring架構中,resourceloader是資源查找定位政策的統一抽象,具體的資源查找定位政策由相應的resourceloader實作類給出。resouceloader的定義如下:

public interface resourceloader {

 string classpath_url_prefix = "classpath:";

 resource getresource(string var1);

 classloader getclassloader();

批量加載資源:resourcepatternresolver

public interface resourcepatternresolver extends resourceloader {

 string classpath_all_url_prefix = "classpath*:";

 resource[] getresources(string var1) throws ioexception;

最後,可以用一張圖表示spring的統一資源加載政策,如下圖所示:

resource和resource loader層次圖

回過頭來,再看下beanfactory和applicationcontext的繼承關系圖:

beanfactory和applicationcontext的繼承關系圖

applicationcontext繼承了resourcepatternresolver,當然就間接實作了resourceloader接口。是以,任何的applicationcontext實作都可以看作是一個resourceloader甚至resourcepatternresolver。而這就是applicationcontext支援spring内統一資源加載政策的真相。

通常,所有的applicationcontext實作類會直接或者間接地繼承org.springframework.context.support.abstractapplicationcontext,從這個類上,我們就可以看到application-context與resourceloader之間的所有關系。abstractapplicationcontext繼承了defaultre-sourceloader,那麼,它的getresource(string)當然就直接用defaultresourceloader的了。

剩下需要它“效勞”的,就是resourcepatternresolver的resource[]getresources (string),當然,abstractapplicationcontext也不負衆望,當即拿下。abstractapplicationcontext類的内部聲明有一個resourcepatternresolver,類型是resourcepatternresolver,對應的執行個體類型為pathmatchingresourcepatternresolver 。

之前我們說過pathmatchingresourcepattern-resolver構造的時候會接受一個resourceloader,而abstractapplicationcontext本身又繼承自defaultresourceloader,當然就直接把自身給“貢獻”了。這樣,整個applicationcontext的實作類就完全可以支援resourceloader或者resourcepatternresolver接口,你能說application-context不支援spring的統一資源加載嗎?說白了,applicationcontext的實作類在作為resourceloader或者resourcepatternresolver時候的行為,完全就是委派給了pathmatchingresource-patternresolver和defaultresourceloader來做。