2018-10-06
原文推薦 死磕 Spring
統(tǒng)一資源:Resource
org.springframework.core.io.Resource 為 Spring 框架所有資源的抽象和訪問接口,它繼承 org.springframework.core.io.InputStreamSource接口。作為所有資源的統(tǒng)一抽象固耘,Source 定義了一些通用的方法,由子類 AbstractResource 提供統(tǒng)一的默認實現(xiàn)糕韧。
Resource 根據(jù)資源的不同類型提供不同的具體實現(xiàn),如下:
FileSystemResource:對 java.io.File 類型資源的封裝,只要是跟 File 打交道的既绕,基本上與 FileSystemResource 也可以打交道缴挖。支持文件和 URL 的形式袋狞,實現(xiàn) WritableResource 接口,且從 Spring Framework 5.0 開始映屋,F(xiàn)ileSystemResource 使用NIO.2 API進行讀/寫交互
ByteArrayResource:對字節(jié)數(shù)組提供的數(shù)據(jù)的封裝苟鸯。如果通過 InputStream 形式訪問該類型的資源,該實現(xiàn)會根據(jù)字節(jié)數(shù)組的數(shù)據(jù)構造一個相應的 ByteArrayInputStream棚点。
UrlResource:對 java.net.URL類型資源的封裝早处。內(nèi)部委派 URL 進行具體的資源操作。
ClassPathResource:class path 類型資源的實現(xiàn)瘫析。使用給定的 ClassLoader 或者給定的 Class 來加載資源砌梆。
InputStreamResource:將給定的 InputStream 作為一種資源的 Resource 的實現(xiàn)類默责。
AbstractResource 為 Resource 接口的默認實現(xiàn),它實現(xiàn)了 Resource 接口的大部分的公共實現(xiàn)么库,作為 Resource 接口中的重中之重
如果我們想要實現(xiàn)自定義的 Resource傻丝,記住不要實現(xiàn) Resource 接口,而應該繼承 AbstractResource 抽象類诉儒,然后根據(jù)當前的具體資源特性覆蓋相應的方法即可葡缰。
統(tǒng)一資源定位:ResourceLoader
Resource 定義了統(tǒng)一的資源,那資源的加載則由 ResourceLoader 來統(tǒng)一定義忱反。
ResourceLoader 接口提供兩個方法:getResource()泛释、getClassLoader()。
getResource()根據(jù)所提供資源的路徑 location 返回 Resource 實例温算,但是它不確保該 Resource 一定存在怜校,需要調用 Resource.exist()方法判斷。該方法支持以下模式的資源加載:
URL位置資源注竿,如”file:C:/test.dat”
ClassPath位置資源茄茁,如”classpath:test.dat”
相對路徑資源,如”WEB-INF/test.dat”巩割,此時返回的Resource實例根據(jù)實現(xiàn)不同而不同
該方法的主要實現(xiàn)是在其子類 DefaultResourceLoader中實現(xiàn)裙顽,具體過程我們在分析DefaultResourceLoader時做詳細說明。
getClassLoader()返回 ClassLoader 實例宣谈,對于想要獲取 ResourceLoader 使用的 ClassLoader 用戶來說愈犹,可以直接調用該方法來獲取,
在分析 Resource 時闻丑,提到了一個類 ClassPathResource 漩怎,這個類是可以根據(jù)指定的 ClassLoader 來加載資源的。
....
總結:
Spring 提供了 Resource 和 ResourceLoader 來統(tǒng)一抽象整個資源及其定位嗦嗡。使得資源與資源的定位有了一個更加清晰的界限勋锤,并且提供了合適的 Default 類,使得自定義實現(xiàn)更加方便和清晰侥祭。
DefaultResource 為 Resource 的默認實現(xiàn)叁执,它對 Resource 接口做了一個統(tǒng)一的實現(xiàn),子類繼承該類后只需要覆蓋相應的方法即可卑硫,同時對于自定義的 Resource 我們也是繼承該類。
DefaultResourceLoader 同樣也是 ResourceLoader 的默認實現(xiàn)蚕断,在自定 ResourceLoader 的時候我們除了可以繼承該類外還可以實現(xiàn) ProtocolResolver 接口來實現(xiàn)自定資源加載協(xié)議欢伏。
DefaultResourceLoader 每次只能返回單一的資源,所以 Spring 針對這個提供了另外一個接口 ResourcePatternResolver 亿乳,該接口提供了根據(jù)指定的 locationPattern 返回多個資源的策略硝拧。其子類 PathMatchingResourcePatternResolver 是一個集大成者的 ResourceLoader 径筏,因為它即實現(xiàn)了 Resource getResource(String location) 也實現(xiàn)了 Resource[] getResources(String locationPattern)。