javascript
Spring中Resource接口详解
原本地址:https://www.cnblogs.com/yw0219/p/7255522.html
在日常程序開發(fā)中,處理外部資源是很繁瑣的事情,我們可能需要處理URL資源、File資源資源、ClassPath相關資源、服務器相關資源(JBoss AS 5.x上的VFS資源)等等很多資源。因此處理這些資源需要使用不同的接口,這就增加了我們系統(tǒng)的復雜性;而且處理這些資源步驟都是類似的(打開資源、讀取資源、關閉資源),因此如果能抽象出一個統(tǒng)一的接口來對這些底層資源進行統(tǒng)一訪問,是不是很方便,而且使我們系統(tǒng)更加簡潔,都是對不同的底層資源使用同一個接口進行訪問。
Spring 提供一個Resource接口來統(tǒng)一這些底層資源一致的訪問,而且提供了一些便利的接口,從而能提供我們的生產力。
4.1.2 Resource接口
Spring的Resource接口代表底層外部資源,提供了對底層外部資源的一致性訪問接口。
Java代碼
public interface InputStreamSource { InputStream getInputStream() throws IOException; }Java代碼
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 relativePath) throws IOException; String getFilename(); String getDescription(); }1)InputStreamSource接口解析:
getInputStream:每次調用都將返回一個新鮮的資源對應的java.io. InputStream字節(jié)流,調用者在使用完畢后必須關閉該資源。
2)Resource接口繼承InputStreamSource接口,并提供一些便利方法:
exists:返回當前Resource代表的底層資源是否存在,true表示存在。
isReadable:返回當前Resource代表的底層資源是否可讀,true表示可讀。
isOpen:返回當前Resource代表的底層資源是否已經打開,如果返回true,則只能被讀取一次然后關閉以避免資源泄露;常見的Resource實現一般返回false。
getURL:如果當前Resource代表的底層資源能由java.util.URL代表,則返回該URL,否則拋出IOException。
getURI:如果當前Resource代表的底層資源能由java.util.URI代表,則返回該URI,否則拋出IOException。
getFile:如果當前Resource代表的底層資源能由java.io.File代表,則返回該File,否則拋出IOException。
contentLength:返回當前Resource代表的底層文件資源的長度,一般是值代表的文件資源的長度。
lastModified:返回當前Resource代表的底層資源的最后修改時間。
createRelative:用于創(chuàng)建相對于當前Resource代表的底層資源的資源,比如當前Resource代表文件資源“d:/test/”則createRelative(“test.txt”)將返回表文件資源“d:/test/test.txt”Resource資源。
getFilename:返回當前Resource代表的底層文件資源的文件路徑,比如File資源“file://d:/test.txt”將返回“d:/test.txt”,而URL資源http://www.javass.cn將返回“”,因為只返回文件路徑。
getDescription:返回當前Resource代表的底層資源的描述符,通常就是資源的全路徑(實際文件名或實際URL地址)。
Resource接口提供了足夠的抽象,足夠滿足我們日常使用。而且提供了很多內置Resource實現:ByteArrayResource、InputStreamResource 、FileSystemResource 、UrlResource 、ClassPathResource、ServletContextResource、VfsResource等。
4.2 內置Resource實現
4.2.1 ByteArrayResource
ByteArrayResource代表byte[]數組資源,對于“getInputStream”操作將返回一個ByteArrayInputStream。
首先讓我們看下使用ByteArrayResource如何處理byte數組資源:
Java代碼 收藏代碼
package cn.javass.spring.chapter4; import java.io.IOException; import java.io.InputStream; import org.junit.Test; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; public class ResourceTest { @Test public void testByteArrayResource() { Resource resource = new ByteArrayResource("Hello World!".getBytes()); if(resource.exists()) { dumpStream(resource); } } }是不是很簡單,讓我們看下“dumpStream”實現:
Java代碼
private void dumpStream(Resource resource) { InputStream is = null; try { //1.獲取文件資源 is = resource.getInputStream(); //2.讀取資源 byte[] descBytes = new byte[is.available()]; is.read(descBytes); System.out.println(new String(descBytes)); } catch (IOException e) { e.printStackTrace(); } finally { try { //3.關閉資源 is.close(); } catch (IOException e) { } } }讓我們來仔細看一下代碼,dumpStream方法很抽象定義了訪問流的三部曲:打開資源、讀取資源、關閉資源,所以dunpStrean可以再進行抽象從而能在自己項目中使用;byteArrayResourceTest測試方法,也定義了基本步驟:定義資源、驗證資源存在、訪問資源。
ByteArrayResource可多次讀取數組資源,即isOpen ()永遠返回false。
1.2.2 InputStreamResource
InputStreamResource代表java.io.InputStream字節(jié)流,對于“getInputStream ”操作將直接返回該字節(jié)流,因此只能讀取一次該字節(jié)流,即“isOpen”永遠返回true。
讓我們看下測試代碼吧:
Java代碼
@Test public void testInputStreamResource() { ByteArrayInputStream bis = new ByteArrayInputStream("Hello World!".getBytes()); Resource resource = new InputStreamResource(bis); if(resource.exists()) { dumpStream(resource); } Assert.assertEquals(true, resource.isOpen()); }測試代碼幾乎和ByteArrayResource測試完全一樣,注意“isOpen”此處用于返回true。
4.2.3 FileSystemResource
FileSystemResource代表java.io.File資源,對于“getInputStream ”操作將返回底層文件的字節(jié)流,“isOpen”將永遠返回false,從而表示可多次讀取底層文件的字節(jié)流。
讓我們看下測試代碼吧:
Java代碼
@Test public void testFileResource() { File file = new File("d:/test.txt"); Resource resource = new FileSystemResource(file); if(resource.exists()) { dumpStream(resource); } Assert.assertEquals(false, resource.isOpen()); }注意由于“isOpen”將永遠返回false,所以可以多次調用dumpStream(resource)。
4.2.4 ClassPathResource
ClassPathResource代表classpath路徑的資源,將使用ClassLoader進行加載資源。classpath 資源存在于類路徑中的文件系統(tǒng)中或jar包里,且“isOpen”永遠返回false,表示可多次讀取資源。
ClassPathResource加載資源替代了Class類和ClassLoader類的“getResource(String name)”和“getResourceAsStream(String name)”兩個加載類路徑資源方法,提供一致的訪問方式。
ClassPathResource提供了三個構造器:
public ClassPathResource(String path):使用默認的ClassLoader加載“path”類路徑資源;
public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加載“path”類路徑資源;
比如當前類路徑是“cn.javass.spring.chapter4.ResourceTest”,而需要加載的資源路徑是“cn/javass/spring/chapter4/test1.properties”,則將加載的資源在“cn/javass/spring/chapter4/test1.properties”;
public ClassPathResource(String path, Class
2)使用指定的ClassLoader進行加載資源,將加載指定的ClassLoader類路徑上相對于根路徑的資源:
Java代碼
@Test public void testClasspathResourceByClassLoader() throws IOException { ClassLoader cl = this.getClass().getClassLoader(); Resource resource = new ClassPathResource("cn/javass/spring/chapter4/test1.properties" , cl); if(resource.exists()) { dumpStream(resource); } System.out.println("path:" + resource.getFile().getAbsolutePath()); Assert.assertEquals(false, resource.isOpen()); }3)使用指定的類進行加載資源,將嘗試加載相對于當前類的路徑的資源:
Java代碼
@Test public void testClasspathResourceByClass() throws IOException { Class clazz = this.getClass(); Resource resource1 = new ClassPathResource("cn/javass/spring/chapter4/test1.properties" , clazz); if(resource1.exists()) { dumpStream(resource1); } System.out.println("path:" + resource1.getFile().getAbsolutePath()); Assert.assertEquals(false, resource1.isOpen()); Resource resource2 = new ClassPathResource("test1.properties" , this.getClass()); if(resource2.exists()) { dumpStream(resource2); } System.out.println("path:" + resource2.getFile().getAbsolutePath()); Assert.assertEquals(false, resource2.isOpen()); }“resource1”將加載cn/javass/spring/chapter4/cn/javass/spring/chapter4/test1.properties資源;“resource2”將加載“cn/javass/spring/chapter4/test1.properties”;
4)加載jar包里的資源,首先在當前類路徑下找不到,最后才到Jar包里找,而且在第一個Jar包里找到的將被返回:
Java代碼
@Test public void classpathResourceTestFromJar() throws IOException { Resource resource = new ClassPathResource("overview.html"); if(resource.exists()) { dumpStream(resource); } System.out.println("path:" + resource.getURL().getPath()); Assert.assertEquals(false, resource.isOpen()); }如果當前類路徑包含“overview.html”,在項目的“resources”目錄下,將加載該資源,否則將加載Jar包里的“overview.html”,而且不能使用“resource.getFile()”,應該使用“resource.getURL()”,因為資源不存在于文件系統(tǒng)而是存在于jar包里,URL類似于“file:/C:/…/*.jar!/overview.html”。
類路徑一般都是相對路徑,即相對于類路徑或相對于當前類的路徑,因此如果使用“/test1.properties”帶前綴“/”的路徑,將自動刪除“/”得到“test1.properties”。
4.2.5 UrlResource
UrlResource代表URL資源,用于簡化URL資源訪問。“isOpen”永遠返回false,表示可多次讀取資源。
UrlResource一般支持如下資源訪問:
http:通過標準的http協(xié)議訪問web資源,如new UrlResource(“http://地址”);
ftp:通過ftp協(xié)議訪問資源,如new UrlResource(“ftp://地址”);
file:通過file協(xié)議訪問本地文件系統(tǒng)資源,如new UrlResource(“file:d:/test.txt”);
具體使用方法在此就不演示了,可以參考cn.javass.spring.chapter4.ResourceTest中urlResourceTest測試方法。
4.2.6 ServletContextResource
ServletContextResource代表web應用資源,用于簡化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作;在此就不具體演示了。
4.2.7 VfsResource
VfsResource代表Jboss 虛擬文件系統(tǒng)資源。
Jboss VFS(Virtual File System)框架是一個文件系統(tǒng)資源訪問的抽象層,它能一致的訪問物理文件系統(tǒng)、jar資源、zip資源、war資源等,VFS能把這些資源一致的映射到一個目錄上,訪問它們就像訪問物理文件資源一樣,而其實這些資源不存在于物理文件系統(tǒng)。
在示例之前需要準備一些jar包,在此我們使用的是Jboss VFS3版本,可以下載最新的Jboss AS 6x,拷貝lib目錄下的“jboss-logging.jar”和“jboss-vfs.jar”兩個jar包拷貝到我們項目的lib目錄中并添加到“Java Build Path”中的“Libaries”中。
讓我們看下示例(cn.javass.spring.chapter4.ResourceTest):
Java代碼
@Test public void testVfsResourceForRealFileSystem() throws IOException { //1.創(chuàng)建一個虛擬的文件目錄 VirtualFile home = VFS.getChild("/home"); //2.將虛擬目錄映射到物理的目錄 VFS.mount(home, new RealFileSystem(new File("d:"))); //3.通過虛擬目錄獲取文件資源 VirtualFile testFile = home.getChild("test.txt"); //4.通過一致的接口訪問 Resource resource = new VfsResource(testFile); if(resource.exists()) { dumpStream(resource); } System.out.println("path:" + resource.getFile().getAbsolutePath()); Assert.assertEquals(false, resource.isOpen()); } @Test public void testVfsResourceForJar() throws IOException { //1.首先獲取jar包路徑 File realFile = new File("lib/org.springframework.beans-3.0.5.RELEASE.jar"); //2.創(chuàng)建一個虛擬的文件目錄 VirtualFile home = VFS.getChild("/home2"); //3.將虛擬目錄映射到物理的目錄 VFS.mountZipExpanded(realFile, home, TempFileProvider.create("tmp", Executors.newScheduledThreadPool(1))); //4.通過虛擬目錄獲取文件資源 VirtualFile testFile = home.getChild("META-INF/spring.handlers"); Resource resource = new VfsResource(testFile); if(resource.exists()) { dumpStream(resource); } System.out.println("path:" + resource.getFile().getAbsolutePath()); Assert.assertEquals(false, resource.isOpen()); }通過VFS,對于jar里的資源和物理文件系統(tǒng)訪問都具有一致性,此處只是簡單示例,如果需要請到Jboss官網深入學習。
4.3.1 ResourceLoader接口
ResourceLoader接口用于返回Resource對象;其實現可以看作是一個生產Resource的工廠類。
Java代碼
public interface ResourceLoader { Resource getResource(String location); ClassLoader getClassLoader(); }getResource接口用于根據提供的location參數返回相應的Resource對象;而getClassLoader則返回加載這些Resource的ClassLoader。
Spring提供了一個適用于所有環(huán)境的DefaultResourceLoader實現,可以返回ClassPathResource、UrlResource;還提供一個用于web環(huán)境的ServletContextResourceLoader,它繼承了DefaultResourceLoader的所有功能,又額外提供了獲取ServletContextResource的支持。
ResourceLoader在進行加載資源時需要使用前綴來指定需要加載:“classpath:path”表示返回ClasspathResource,“http://path”和“file:path”表示返回UrlResource資源,如果不加前綴則需要根據當前上下文來決定,DefaultResourceLoader默認實現可以加載classpath資源,如代碼所示(cn.javass.spring.chapter4.ResourceLoaderTest):
Java代碼
@Test public void testResourceLoad() { ResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource("classpath:cn/javass/spring/chapter4/test1.txt"); //驗證返回的是ClassPathResource Assert.assertEquals(ClassPathResource.class, resource.getClass()); Resource resource2 = loader.getResource("file:cn/javass/spring/chapter4/test1.txt"); //驗證返回的是ClassPathResource Assert.assertEquals(UrlResource.class, resource2.getClass()); Resource resource3 = loader.getResource("cn/javass/spring/chapter4/test1.txt"); //驗證返默認可以加載ClasspathResource Assert.assertTrue(resource3 instanceof ClassPathResource); }對于目前所有ApplicationContext都實現了ResourceLoader,因此可以使用其來加載資源。
ClassPathXmlApplicationContext:不指定前綴將返回默認的ClassPathResource資源,否則將根據前綴來加載資源;
FileSystemXmlApplicationContext:不指定前綴將返回FileSystemResource,否則將根據前綴來加載資源;
WebApplicationContext:不指定前綴將返回ServletContextResource,否則將根據前綴來加載資源;
其他:不指定前綴根據當前上下文返回Resource實現,否則將根據前綴來加載資源。
4.3.2 ResourceLoaderAware接口
ResourceLoaderAware是一個標記接口,用于通過ApplicationContext上下文注入ResourceLoader。
Java代碼
public interface ResourceLoaderAware { void setResourceLoader(ResourceLoader resourceLoader); }讓我們看下測試代碼吧:
1) 首先準備測試Bean,我們的測試Bean還簡單只需實現ResourceLoaderAware接口,然后通過回調將ResourceLoader保存下來就可以了:
Java代碼
package cn.javass.spring.chapter4.bean; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.ResourceLoader; public class ResourceBean implements ResourceLoaderAware { private ResourceLoader resourceLoader; @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public ResourceLoader getResourceLoader() { return resourceLoader; } }2) 配置Bean定義(chapter4/resourceLoaderAware.xml):
Java代碼
<bean class="cn.javass.spring.chapter4.bean.ResourceBean"/>3)測試(cn.javass.spring.chapter4.ResoureLoaderAwareTest):
Java代碼
@Test public void test() { ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter4/resourceLoaderAware.xml"); ResourceBean resourceBean = ctx.getBean(ResourceBean.class); ResourceLoader loader = resourceBean.getResourceLoader(); Assert.assertTrue(loader instanceof ApplicationContext); }注意此處“l(fā)oader instanceof ApplicationContext”,說明了ApplicationContext就是個ResoureLoader。
由于上述實現回調接口注入ResourceLoader的方式屬于侵入式,所以不推薦上述方法,可以采用更好的自動注入方式,如“byType”和“constructor”,此處就不演示了。
4.3.3 注入Resource
通過回調或注入方式注入“ResourceLoader”,然后再通過“ResourceLoader”再來加載需要的資源對于只需要加載某個固定的資源是不是很麻煩,有沒有更好的方法類似于前邊實例中注入“java.io.File”類似方式呢?
Spring提供了一個PropertyEditor “ResourceEditor”用于在注入的字符串和Resource之間進行轉換。因此可以使用注入方式注入Resource。
ResourceEditor完全使用ApplicationContext根據注入的路徑字符串獲取相應的Resource,說白了還是自己做還是容器幫你做的問題。
接下讓我們看下示例:
1)準備Bean:
Java代碼
package cn.javass.spring.chapter4.bean; import org.springframework.core.io.Resource; public class ResourceBean3 { private Resource resource; public Resource getResource() { return resource; } public void setResource(Resource resource) { this.resource = resource; } }2)準備配置文件(chapter4/ resourceInject.xml):
Java代碼
<bean id="resourceBean1" class="cn.javass.spring.chapter4.bean.ResourceBean3"> <property name="resource" value="cn/javass/spring/chapter4/test1.properties"/> </bean> <bean id="resourceBean2" class="cn.javass.spring.chapter4.bean.ResourceBean3"> <property name="resource" value="classpath:cn/javass/spring/chapter4/test1.properties"/> </bean>注意此處“resourceBean1”注入的路徑沒有前綴表示根據使用的ApplicationContext實現進行選擇Resource實現。
3)讓我們來看下測試代碼(cn.javass.spring.chapter4.ResourceInjectTest)吧:
Java代碼
@Test public void test() { ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter4/resourceInject.xml"); ResourceBean3 resourceBean1 = ctx.getBean("resourceBean1", ResourceBean3.class); ResourceBean3 resourceBean2 = ctx.getBean("resourceBean2", ResourceBean3.class); Assert.assertTrue(resourceBean1.getResource() instanceof ClassPathResource); Assert.assertTrue(resourceBean2.getResource() instanceof ClassPathResource); }接下來一節(jié)讓我們深入ApplicationContext對各種Resource的支持,及如何使用更便利的資源加載方式。
4.4.1 使用路徑通配符加載Resource
前面介紹的資源路徑都是非常簡單的一個路徑匹配一個資源,Spring還提供了一種更強大的Ant模式通配符匹配,從能一個路徑匹配一批資源。
Ant路徑通配符支持“?”、“”、“*”,注意通配符匹配不包括目錄分隔符“/”:
“?”:匹配一個字符,如“config?.xml”將匹配“config1.xml”;
“”:匹配零個或多個字符串,如“cn//config.xml”將匹配“cn/javass/config.xml”,但不匹配匹配“cn/config.xml”;而“cn/config-*.xml”將匹配“cn/config-dao.xml”;
“”:匹配路徑中的零個或多個目錄,如“cn//config.xml”將匹配“cn /config.xml”,也匹配“cn/javass/spring/config.xml”;而“cn/javass/config-.xml”將匹配“cn/javass/config-dao.xml”,即把“”當做兩個“*”處理。
Spring提供AntPathMatcher來進行Ant風格的路徑匹配。具體測試請參考cn.javass.spring.chapter4. AntPathMatcherTest。
Spring在加載類路徑資源時除了提供前綴“classpath:”的來支持加載一個Resource,還提供一個前綴“classpath*:”來支持加載所有匹配的類路徑Resource。
Spring提供ResourcePatternResolver接口來加載多個Resource,該接口繼承了ResourceLoader并添加了“Resource[] getResources(String locationPattern)”用來加載多個Resource:
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = “classpath*:”;
Resource[] getResources(String locationPattern) throws IOException;
}
Spring提供了一個ResourcePatternResolver實現PathMatchingResourcePatternResolver,它是基于模式匹配的,默認使用AntPathMatcher進行路徑匹配,它除了支持ResourceLoader支持的前綴外,還額外支持“classpath*:”用于加載所有匹配的類路徑Resource,ResourceLoader不支持前綴“classpath*:”:
首先做下準備工作,在項目的“resources”創(chuàng)建“META-INF”目錄,然后在其下創(chuàng)建一個“INDEX.LIST”文件。同時在“org.springframework.beans-3.0.5.RELEASE.jar”和“org.springframework.context-3.0.5.RELEASE.jar”兩個jar包里也存在相同目錄和文件。然后創(chuàng)建一個“LICENSE”文件,該文件存在于“com.springsource.cn.sf.cglib-2.2.0.jar”里。
一、“classpath”: 用于加載類路徑(包括jar包)中的一個且僅一個資源;對于多個匹配的也只返回一個,所以如果需要多個匹配的請考慮“classpath*:”前綴;
@Test public void testClasspathPrefix() throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //只加載一個絕對匹配Resource,且通過ResourceLoader.getResource進行加載 Resource[] resources=resolver.getResources("classpath:META-INF/INDEX.LIST"); Assert.assertEquals(1, resources.length); //只加載一個匹配的Resource,且通過ResourceLoader.getResource進行加載 resources = resolver.getResources("classpath:META-INF/*.LIST"); Assert.assertTrue(resources.length == 1); }二、“classpath*”: 用于加載類路徑(包括jar包)中的所有匹配的資源。帶通配符的classpath使用“ClassLoader”的“Enumeration getResources(String name)”方法來查找通配符之前的資源,然后通過模式匹配來獲取匹配的資源。如“classpath:META-INF/*.LIST”將首先加載通配符之前的目錄“META-INF”,然后再遍歷路徑進行子路徑匹配從而獲取匹配的資源。
@Test public void testClasspathAsteriskPrefix () throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //將加載多個絕對匹配的所有Resource //將首先通過ClassLoader.getResources("META-INF")加載非模式路徑部分 //然后進行遍歷模式匹配 Resource[] resources=resolver.getResources("classpath*:META-INF/INDEX.LIST"); Assert.assertTrue(resources.length > 1); //將加載多個模式匹配的Resource resources = resolver.getResources("classpath*:META-INF/*.LIST"); Assert.assertTrue(resources.length > 1); }注意“resources.length >1”說明返回多個Resource。不管模式匹配還是非模式匹配只要匹配的都將返回。
在“com.springsource.cn.sf.cglib-2.2.0.jar”里包含“asm-license.txt”文件,對于使用“classpath*: asm-*.txt”進行通配符方式加載資源將什么也加載不了“asm-license.txt”文件,注意一定是模式路徑匹配才會遇到這種問題。這是由于“ClassLoader”的“getResources(String name)”方法的限制,對于name為“”的情況將只返回文件系統(tǒng)的類路徑,不會包換jar包根路徑。
@Test public void testClasspathAsteriskPrefixLimit() throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //將首先通過ClassLoader.getResources("")加載目錄, //將只返回文件系統(tǒng)的類路徑不返回jar的跟路徑 //然后進行遍歷模式匹配 Resource[] resources = resolver.getResources("classpath*:asm-*.txt"); Assert.assertTrue(resources.length == 0); //將通過ClassLoader.getResources("asm-license.txt")加載 //asm-license.txt存在于com.springsource.net.sf.cglib-2.2.0.jar resources = resolver.getResources("classpath*:asm-license.txt"); Assert.assertTrue(resources.length > 0); //將只加載文件系統(tǒng)類路徑匹配的Resource resources = resolver.getResources("classpath*:LICENS*"); Assert.assertTrue(resources.length == 1); }對于“resolver.getResources(“classpath*:asm-.txt”);”,由于在項目“resources”目錄下沒有所以應該返回0個資源;“resolver.getResources(“classpath:asm-license.txt”);”將返回jar包里的Resource;“resolver.getResources(“classpath*:LICENS*”);”,因為將只返回文件系統(tǒng)類路徑資源,所以返回1個資源。
因此加載通配符路徑時(即路徑中包含通配符),必須包含一個根目錄才能保證加載的資源是所有的,而不是部分。
三、“file”:加載一個或多個文件系統(tǒng)中的Resource。如“file:D:/*.txt”將返回D盤下的所有txt文件;
四、無前綴:通過ResourceLoader實現加載一個資源。
AppliacationContext提供的getResources方法將獲取資源委托給ResourcePatternResolver實現,默認使用PathMatchingResourcePatternResolver。所有在此就無需介紹其使用方法了。
4.4.2 注入Resource數組
Spring還支持注入Resource數組,直接看配置如下:
“resourceBean1”就不用多介紹了,傳統(tǒng)實現方式;對于“resourceBean2”則使用前綴“classpath*”,看到這大家應該懂的,加載匹配多個資源;“resourceBean3”是混合使用的;測試代碼在“cn.javass.spring.chapter4.ResourceInjectTest.testResourceArrayInject”。
Spring通過ResourceArrayPropertyEditor來進行類型轉換的,而它又默認使用“PathMatchingResourcePatternResolver”來進行把路徑解析為Resource對象。所有大家只要會使用“PathMatchingResourcePatternResolver”,其它一些實現都是委托給它的,比如AppliacationContext的“getResources”方法等。
4.4.3 AppliacationContext實現對各種Resource的支持
一、ClassPathXmlApplicationContext:默認將通過classpath進行加載返回ClassPathResource,提供兩類構造器方法:
第一類構造器是根據提供的配置文件路徑使用“ResourcePatternResolver ”的“getResources()”接口通過匹配獲取資源;即如“classpath:config.xml”
第二類構造器則是根據提供的路徑和clazz來構造ClassResource資源。即采用“public ClassPathResource(String path, Class
//linux系統(tǒng),以下全是相對于當前vm路徑進行加載
new FileSystemXmlApplicationContext(“chapter4/config.xml”);
new FileSystemXmlApplicationContext(“/chapter4/confg.xml”);
//windows系統(tǒng),第一個將相對于當前vm路徑進行加載;
//第二個則是絕對路徑方式加載
new FileSystemXmlApplicationContext(“chapter4/config.xml”);
new FileSystemXmlApplicationContext(“d:/chapter4/confg.xml”);
此處還需要注意:在linux系統(tǒng)上,構造器使用的是相對路徑,而ctx.getResource()方法如果以“/”開頭則表示獲取絕對路徑資源,而不帶前導“/”將返回相對路徑資源。如下:
//linux系統(tǒng),第一個將相對于當前vm路徑進行加載;
//第二個則是絕對路徑方式加載
ctx.getResource (“chapter4/config.xml”);
ctx.getResource (“/root/confg.xml”);
//windows系統(tǒng),第一個將相對于當前vm路徑進行加載;
//第二個則是絕對路徑方式加載
ctx.getResource (“chapter4/config.xml”);
ctx.getResource (“d:/chapter4/confg.xml”);
因此如果需要加載絕對路徑資源最好選擇前綴“file”方式,將全部根據絕對路徑加載。如在linux系統(tǒng)“ctx.getResource (“file:/root/confg.xml”);”
總結
以上是生活随笔為你收集整理的Spring中Resource接口详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CC2540F256RHAR
- 下一篇: python布尔值使用_如何在Pytho