Spring中的資源文件框架——Resource

Spring中資源加載的框架

Spring對(duì)于資源加載有著一套自己的框架——Resource掷豺,Resource繼承自InputStream捞烟。
下面的是Resource的源碼:

public interface Resource extends InputStreamSource {

    boolean exists();
    default boolean isReadable() {
        return true;
    }
    default boolean isOpen() {
        return false;
    }
    default boolean isFile() {
        return false;
    }
    URL getURL() throws IOException;
    URI getURI() throws IOException;
    File getFile() throws IOException;
    default ReadableByteChannel readableChannel() throws IOException {
        return Channels.newChannel(getInputStream());
    }
    long contentLength() throws IOException;
    long lastModified() throws IOException;
    Resource createRelative(String relativePath) throws IOException;
    @Nullable
    String getFilename();
    String getDescription();

}

  • exists() 判斷資源是否存在
  • isOpen() 判斷資源是否打開(kāi)
  • isFile() 判斷資源是否是一個(gè)文件
  • getURL() 獲取資源文件的URL
  • getURI() 獲取資源文件的URI
  • readableChannel()這個(gè)方法接口中有默認(rèn)實(shí)現(xiàn),返回的是ReadableByteChannel当船,這個(gè)類屬于Java的NIO中的管道题画。
  • contentLength() 獲取內(nèi)容的長(zhǎng)度,這個(gè)方法返回一個(gè)long德频,因?yàn)槲募?nèi)容可能很長(zhǎng)苍息。
  • lastModified() 這個(gè)方法返回的是最后修改時(shí)間,雖然也返回的是long壹置,但是這個(gè)數(shù)字是一個(gè)時(shí)間戳竞思。
  • createRelative(String relativePath) 這個(gè)方法根據(jù)relativePath返回一個(gè)相對(duì)與該Resource的Resource。
  • getFilename() 獲取文件的名字钞护。
  • getDescription 獲取一個(gè)對(duì)該資源的一個(gè)描述盖喷。

下面的是Resource的繼承圖:(這里只是一部分)


Resource的繼承圖.png
  • WritableResource:可寫(xiě)資源接口,是Spring3.1版本新增的接口难咕,有兩個(gè)實(shí)現(xiàn)類FileSystemResource和PathResource课梳,其中PathResource是Spring4.0提供的實(shí)現(xiàn)類距辆。
  • ByteArrayResource:二進(jìn)制數(shù)組表示的資源,二進(jìn)制數(shù)組資源可以在內(nèi)存中通過(guò)程序構(gòu)造惦界。
  • ClassPathResource:類路徑下的資源挑格,資源以相對(duì)路徑的方式表示。
  • FileSystemResource:文件系統(tǒng)資源沾歪,資源一文件系統(tǒng)的路徑表示漂彤,如D:/aaa/vvv.java
  • InputStreamResource:以輸入流表示返回的資源。
  • ServletContextResource:問(wèn)訪問(wèn)Web容器上下文中的資源而設(shè)計(jì)的類灾搏,負(fù)責(zé)對(duì)于Web應(yīng)用根目錄的路徑加載資源挫望。它支持以流和URL的方式訪問(wèn),在WAR解包的情況下狂窑,也可以通過(guò)File方式訪問(wèn)媳板。該類還可以直接從JAR包中訪問(wèn)資源。
  • UrlResource:URL封裝了java.net.URL泉哈,它使用戶能夠訪問(wèn)任任何可以通過(guò)URL表示的資源蛉幸,如文件系統(tǒng)的資源、HTTP資源丛晦、FTP資源等奕纫。
  • PathResource:Spring4.0提供的讀取資源文件的新類。Path封裝了java.net.URL烫沙、java.nio.Path匹层、文件系統(tǒng)資源,它使用戶能夠訪問(wèn)任何可以通過(guò)URL锌蓄、Path升筏、系統(tǒng)文件路徑表示的資源,如文件系統(tǒng)的資源瘸爽,HTTP資源您访、FTP資源等。
    和JDK提供的File類訪問(wèn)資源比起來(lái)剪决,Spring的Resource實(shí)現(xiàn)類提供了更加便捷的訪問(wèn)方式灵汪,用戶可以根據(jù)實(shí)際的情況選擇合適的Resource訪問(wèn)資源。下面的是一個(gè)示例:
package top.mcwebsite.resource;

import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.WritableResource;

import java.io.*;

public class FileResourceTest {

    @Test
    public void testResource() throws IOException {
        String filePath = "E:\\源碼\\Spring源碼閱讀\\testSpring\\src\\test\\resources\\spring.txt";

        // 1. 使用系統(tǒng)的文件路徑方式加載文件
        WritableResource resource1 = new PathResource(filePath);

        // 2. 使用類路徑方式加載文件
        Resource resource2 = new ClassPathResource("spring.txt");

        // 3. 使用WritableResource接口寫(xiě)資源文件
        OutputStream os = resource1.getOutputStream();
        os.write("Spring是一套非常優(yōu)秀的框架".getBytes());

        // 4. 使用Resource接口讀文件
        InputStream in1 = resource1.getInputStream();
        InputStream in2 = resource1.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(in1);
        byte[] bytes = new byte[1024];
        bis.read(bytes);
        System.out.println(new String(bytes));
        System.out.println("resource1: " + resource1.getFilename());
        System.out.println("resource2: " + resource2.getFilename());
    }
}

隨之而來(lái)的問(wèn)題及解決

那就是Resource的選擇昼捍,這么多的Resource如何知道選擇使用哪一個(gè)识虚?Spring提供了一個(gè)強(qiáng)大的資源加載機(jī)制肢扯,妒茬,他可以通過(guò)前綴標(biāo)識(shí)加載資源,如:classpath, file等蔚晨,同時(shí)還支持使用Ant風(fēng)格的通配符乍钻。

  1. 資源地址的表示
地址前綴 示例 對(duì)應(yīng)的資源類型
classpath: classpath:top/mcwebsite/resource/bean.xml 從類路徑中加載資源肛循,classpath:和classpath:/是等價(jià)的,都是相對(duì)于類的路徑银择。資源文件可以在標(biāo)準(zhǔn)的文件系統(tǒng)中多糠,也可以在JAR和ZIP的類包中
file: file:/config/bean,xml 使用UrlResource從文件系統(tǒng)目錄中裝載資源,可采用絕對(duì)或相對(duì)路徑
http:// http://www.mcwebsite.top/bean.xml 使用UrlResource從Web服務(wù)器中裝載資源
ftp:// ftp://www.mcwebsite.top/bean.xml 使用UrlResource從ftp服務(wù)器中裝載資源
沒(méi)有前綴 com/mcwebsite/resource/bean.xml 根據(jù)ApplicationContext的具體實(shí)現(xiàn)曹勇對(duì)應(yīng)類型的Resource

關(guān)于classpath:和classpath:前綴浩考。如果有多個(gè)JAR包或文件系統(tǒng)路徑都擁有同一個(gè)相同的包夹孔。classpath:只會(huì)找到第一個(gè)加載的,而classpath:會(huì)掃描所有的這些JAR包及類路徑下出現(xiàn)的析孽。

Ant風(fēng)格的資源地址支持三種通配符:

  • ?:匹配文件名中的一個(gè)字符
  • *:匹配文件名中的多個(gè)字符
  • **:匹配多層路徑搭伤。

ResourceLoader接口僅有一個(gè)getResource(String location)方法,可根據(jù)資源地址加載資源袜瞬。不過(guò)怜俐,資源地址僅支持帶資源類型前綴的表達(dá)式,不支持Ant風(fēng)格的資源路徑表達(dá)式邓尤。ResourcePatternResolver擴(kuò)展ResourceLoader接口拍鲤,定義了一個(gè)新的接口方法getResources(String locationPatern),該方法支持帶資源前綴及Ant風(fēng)格的資源路徑表達(dá)式汞扎。


import java.io.IOException;
import static org.junit.Assert.assertNotNull;
public class PatternResolverTest {
    @Test
    public void getResources() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath:*.xml");
        assertNotNull(resources);
        for (Resource resource : resources) {
            System.out.println(resource.getDescription());
        }
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末季稳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子佩捞,更是在濱河造成了極大的恐慌绞幌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件一忱,死亡現(xiàn)場(chǎng)離奇詭異莲蜘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)帘营,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)票渠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芬迄,你說(shuō)我怎么就攤上這事问顷。” “怎么了禀梳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵杜窄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我算途,道長(zhǎng)塞耕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任嘴瓤,我火速辦了婚禮扫外,結(jié)果婚禮上莉钙,老公的妹妹穿的比我還像新娘。我一直安慰自己筛谚,他們只是感情好磁玉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著驾讲,像睡著了一般蚊伞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吮铭,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天厚柳,我揣著相機(jī)與錄音,去河邊找鬼沐兵。 笑死别垮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扎谎。 我是一名探鬼主播碳想,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毁靶!你這毒婦竟也來(lái)了胧奔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤预吆,失蹤者是張志新(化名)和其女友劉穎龙填,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拐叉,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岩遗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凤瘦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宿礁。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蔬芥,靈堂內(nèi)的尸體忽然破棺而出梆靖,到底是詐尸還是另有隱情,我是刑警寧澤笔诵,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布返吻,位于F島的核電站,受9級(jí)特大地震影響乎婿,放射性物質(zhì)發(fā)生泄漏测僵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一次酌、第九天 我趴在偏房一處隱蔽的房頂上張望恨课。 院中可真熱鬧,春花似錦岳服、人聲如沸剂公。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纲辽。三九已至,卻和暖如春璃搜,著一層夾襖步出監(jiān)牢的瞬間拖吼,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工这吻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吊档,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓唾糯,卻偏偏與公主長(zhǎng)得像怠硼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子移怯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容