spring——(5)Resource
来源:互联网 发布:卓行信贷网络借贷 编辑:程序博客网 时间:2024/05/20 10:21
在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理URL资源、File资源资源、ClassPath相关资源、服务器相关资源(JBoss AS 5.x上的VFS资源)等等很多资源。因此处理这些资源需要使用不同的接口,这就增加了我们系统的复杂性;而且处理这些资源步骤都是类似的(打开资源、读取资源、关闭资源),因此如果能抽象出一个统一的接口来对这些底层资源进行统一访问,是不是很方便,而且使我们系统更加简洁,都是对不同的底层资源使用同一个接口进行访问。 Spring 提供一个Resource接口来统一这些底层资源一致的访问,而且提供了一些便利的接口,从而能提供我们的生产力。
Resource接口
Spring的Resource接口代表底层外部资源,提供了对底层外部资源的一致性访问接口。
接口中的方法如下:
- 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:用于创建相对于当前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等。
ResourceLoader 接口
ResourceLoader 接口是用来加载 Resource 对象的,换句话说,就是当一个对象需要获取 Resource 实例时,可以选择实现 ResourceLoader 接口。
public interface ResourceLoader { Resource getResource(String location);}
spring 里所有的应用上下文都是实现了 ResourceLoader 接口,因此,所有应用上下文都可以通过 getResource() 方法获取 Resource 实例。
当你在指定应用上下文调用 getResource() 方法时,而指定的位置路径又没有包含特定的前缀,spring 会根据当前应用上下文来决定返回哪一种类型 Resource。举个例子,假设下面的代码片段是通过 ClassPathXmlApplicationContext 实例来调用的:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
那 spring 会返回一个 ClassPathResource 对象;类似的,如果是通过实例 FileSystemXmlApplicationContext 实例调用的,返回的是一个 FileSystemResource 对象;如果是通过 WebApplicationContext 实例的,返回的是一个 ServletContextResource 对象…… 如上所说,你就可以在指定的应用上下中使用 Resource 实例来加载当前应用上下文的资源。
还有另外一种场景里,如在其他应用上下文里,你可能会强制需要获取一个 ClassPathResource 对象,这个时候,你可以通过加上指定的前缀来实现这一需求,如:
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
类似的,你可以通过其他任意的 url 前缀来强制获取 UrlResource 对象:
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
下面,给出一个表格来总结一下 spring 根据各种位置路径加载资源的策略:
举个例子:
public class TestResource implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void resource() throws IOException { Resource resource = applicationContext.getResource("classpath:test.txt");// ClassPathResource resource = (ClassPathResource) applicationContext.getResource("classpath:test.txt"); System.out.println(resource.getFilename()); System.out.println(resource.contentLength()); }}
这个类实现了ApplicationContextAware 接口,这样就可以获取ApplicationContext 对象,用ApplicationContext 对象获取Resource 。
在类中定义一个resource()方法,在这个方法中获取一个text.txt文件(位置在src/main/resources下)并返回一个Resource对象,这里我是用的是classpath,所以返回的是ClassPathResource对象,只是这里我直接使用Resource接收。
现在在bean中配置一下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="testResource" class="com.mss.test.TestResource"></bean></beans>
写一个测试类:
@RunWith(BlockJUnit4ClassRunner.class)public class TestOneInterface extends UnitTestBase{ public TestOneInterface() { super("classpath*:spring-ioc.xml"); } @Test public void testAutoWriter() { TestResource testResource=super.getBean("testResource"); try { testResource.resource(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
运行结果:
test.txt0
由于是一个空的文件,所以长度是0;
上面的classpath是什么意思?
看一个图片
这个路径就是classpath
我们也可以用file:
public class TestResource implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void resource() throws IOException { Resource resource = applicationContext.getResource("file:D:\\eclipse\\eclipse-workspace\\HelloSpring\\src\\main\\resources\\test.txt"); System.out.println(resource.getFilename()); System.out.println(resource.contentLength()); }}
运行结果是一样的。
在看一下使用http:
public class TestResource implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void resource() throws IOException { Resource resource = applicationContext.getResource("https://www.duba.com/?f=liebao"); System.out.println(resource.getFilename()); System.out.println(resource.contentLength()); }}
这里使用的是毒霸网址导航的链接,看一下运行结果:
?f=liebao256405
如果前缀是空会怎么样?
前面已经说到当你在指定应用上下文调用 getResource() 方法时,而指定的位置路径又没有包含特定的前缀,spring 会根据当前应用上下文来决定返回哪一种类型 Resource。 看一下代码:
public class TestResource implements ApplicationContextAware { private ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void resource() throws IOException { Resource resource = applicationContext.getResource("test.txt"); System.out.println(resource.getFilename()); System.out.println(resource.contentLength()); }}
还记得我们的测试基类吗?
public class UnitTestBase { private ClassPathXmlApplicationContext context; private String springXmlpath; public UnitTestBase() {} public UnitTestBase(String springXmlpath) { this.springXmlpath = springXmlpath; } @Before public void before() { if (StringUtils.isEmpty(springXmlpath)) { springXmlpath = "classpath*:spring-*.xml"; } try { context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+")); context.start(); } catch (BeansException e) { e.printStackTrace(); } } .......................}
我们这里初始化ioc容器时,使用的是ClassPathXmlApplicationContext,所以Spring会把当前没有前缀的Resource 作为classpath前缀处理。
- spring——(5)Resource
- Spring入门——Resource
- Spring源码——Resource
- (七)Spring详解——资源Resource接口
- 【初探Spring】——Spring IOC(三):初始化过程—Resource定位
- spring框架学习笔记(二)——spring的ioc之Resource
- Android(5)——Style Resource
- Spring讲解-----------资源(resource)
- Spring源码分析篇01——Resource
- Spring @Resource
- Spring @Resource
- spring @Resource
- Spring @Resource
- spring resource
- Spring @Resource
- Spring Resource
- spring-resource
- [Spring]Resource
- 用函数编程计算两整数的最大值,在主函数中调用该函数计算并输出从键盘任意输入的两整数的最大值。
- linux hadoop集群启动 本机ssh不能无密码连接
- 2. 调试Zircon前的准备
- 支持向量机
- Java内存区域与内存溢出(二)
- spring——(5)Resource
- Win10 修改git bash的默认开始路径
- phpstorm 调试总是断点在index.php的第一行
- memo
- PHP ajax实现数组返回
- Postgres小版本升级
- rxjava 常用用法实例
- gitlab之:gitlab 403 forbidden 并发引起ip被封
- Eclipse搭建SSH框架(下)包含增删查改-JAVA