Spring系列.Resource接口


接口簡介

JDK中提供了java.net.URL這個類來用於獲取不同種類的資源(根據不同前綴的url可以獲取不同種類的資源)。但是URL這個類沒有獲取classpath和ServletContext下的資源的能力。因此Spring提供了Resource接口,用於獲取各種資源。

Resource接口

spring中的org.springframework.core.io.Resource接口代表着物理存在的任何資源,其繼承於org.springframework.core.io.InputStreamSource。

Spring的資源接口是一個更強大的接口,用於抽象對低級資源的訪問。

Resource接口的主要方法如下:


public interface Resource extends InputStreamSource {

	boolean exists();
	default boolean isReadable() {
		return exists();
	}
	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();
}

關於上面提供的getURI和getURL方法這邊做下解釋。URI用於唯一指定互聯網上一個資源的名字,我們可以理解為一個資源的唯一id。URL代表一個資源的唯一地址,我們通過這個地址可以在互聯網上尋找到這個資源。通常可以用URL來代替URI。

Resource繼承了InputStreamSource接口,下面是其定義:

public interface InputStreamSource {

    InputStream getInputStream() throws IOException;

}

Resource的比較重要的方法如下:

  • getInputStream(): 定位和打開resource, 返回InputStream 來讀取資源。每一次調用都會返回一個新的InputStream,調用者負責將其關閉。
  • exists(): 返回boolean,用來判斷資源是否存在
  • isOpen(): 返回boolean,用來判斷資源是不是已經存在一個open stream處理器。 true表明InputStream不能被多次讀取,那么這次的讀取會被關閉,以避免資源泄露。false是所有正常資源實現的返回,有可能會拋異常:InputStreamResource。
  • getDescription(): 返回資源的描述,用於錯誤輸出。通常這會返回resource URL的全名。

其他的方法可以讓你獲取到代表resource的URL或者File對象。

Resource接口在Spring代碼中非常常用,你也可以考慮應用到你的程序中。

內置的Resource實現

Spring中提供了很多Resource接口的實現類。主要有ByteArrayResource, ClassPathResource, DescriptiveResource, FileSystemResource, InputStreamResource, PortletContextResource, ServletContextResource和UrlResource。常用的有:

  • ClassPathResource:通過 ClassPathResource 以類路徑的方式進行訪問;
  • FileSystemResource:通過 FileSystemResource 以文件系統絕對路徑的方式進行訪問;
  • ServletContextResource:通過 ServletContextResource 以相對於Web應用根目錄的方式進行訪問。
  • UrlResource :通過java.net.URL來訪問資源,當然它也支持File格式,如“file:”、“http:”。

ResourceLoader接口

ResourceLoader接口用來加載Resource資源。

public interface ResourceLoader {
    Resource getResource(String location);
}

所有的ApplicationContext類都實現了ResourceLoader接口,所以我們可以使用context來加載resource。

不同類型的ApplicationContext會返回不同的Resource。

當你在特定的應用程序上下文上調用getResource(),並且指定的位置路徑沒有特定的前綴時,你將返回適合該特定應用程序上下文的資源類型。例如,假設對ClassPathXmlApplicationContext實例執行了以下代碼片段:

Resource template = ctx.getResource("some/resource/path/myTemplate.txt");

ClassPathXmlApplicationContext返回ClassPathResource,FileSystemXmlApplicationContext返回FileSystemResource,WebApplicationContext返回ServletContextResource。 他會返回和ApplicationContext相對應的Resource實現。

當然,你可以強制ClassPathResource使用,而不管ApplicationContext到底是什么。使用的方法就是在資源路徑前面加前綴。

Resource template1 = ctx.getResource("classpath:some/resource/path/myTemplate.txt");

Resource template2 = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");

Resource template3 = ctx.getResource("file:///some/resource/path/myTemplate.txt");

Resource[] template4 = ctx.getResources("file:///some/resource/path/my**a.txt");

ResourceLoaderAware接口

ResourceLoaderAware接口是一個特殊的回調接口,表明該組件需要提供一個ResourceLoader的引用。 下面是ResourceLoaderAware的定義:

public interface ResourceLoaderAware {
    void setResourceLoader(ResourceLoader resourceLoader);
}

一個Bean如果實現了ResourceLoaderAware接口,容器在加載Bean的時候會給這個Bean注入一個ResourceLoad實現類(容器設置的ResourceLoad就是容器本身,因為所有的Spring application contexts 都實現了ResourceLoader 接口),利用這個實現類也可以加載Resource資源。

Resources as Dependencies

不知道在講什么,后續再整理。。。

構造 ApplicationContext

//從classpath下尋找配置文件構造ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
//從當前工作目錄尋找配置文件構造FileSystemXmlApplicationContext
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
//由於加了classpath前綴,所以從classpath下尋找配置構造FileSystemXmlApplicationContext
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
//以MessengerService類所在的路徑為基准路徑,尋找services.xml和daos.xml作為配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"}, MessengerService.class);

通配符形式構造資源

ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM