Spring framework: Resource API

Spring资源管理

Resource接口

  • Resource类似FilePathURL,是Spring提供的对一类资源的抽象 Resource会增加应用与Spring框架的耦合,但实际上它只是一个对于URL等传统资源类的有力替代品和实用API,用其它资源API也是可以的 Resource的好处是:方便,例如能够使用classpath*等路径前缀查找而不需要写完整的文件或URL的路径信息
  • Resource接口包含的日常常用方法:
    • boolean exists():判断资源是否存在
    • boolean isReadable():判断资源是否可读
    • InputStream getInputStream():获取该资源的输入流(继承InputStreamSource接口)
    • ReadableByteChannel readableChannel():获取nio接口
    • String getDescription():获取资源的全路径名,通常用于错误日志输出
  • Resource的常见实现类:
    • UrlResource:是java.net.URL的包装
    • ClassPathResource:表示所有可以从classpath中获取的资源
    • FileSystemResource:是java.io.File以及java.nio.file.Files的包装
    • ServletContextResource:表示所有可以从Web应用中获取的资源
    • ByteArrayResource:表示一个byte数组资源

ResourceLoaderResourcePatternResolver接口

  • 在平时,一般不会直接使用上述的实现类来显式地用new创建Resource实例,而是用ResourceLoaderResourcePatternResolver帮助我们自动地选择实现类
  • ResourceLoader包含两个方法,最常用的是Resource getResource(String loc),用于加载loc指向的资源并自动选择合适的实现类,然后返回Resource实例
  • ResourcePatternResolver继承ResourceLoader接口,此外还包含一个方法Resource[] getResources(String locPattern),用于加载匹配locPattern模式串的所有资源,然后返回Resource[]数组
  • 此前所说的ApplicationContext接口继承了ResourcePatternResolver接口,因此我们不需要额外地创建一个ResourceLoaderResourcePatternResolver实例,而是使用ctx.getResource(loc)ctx.getResources(locPattern)即可
  • String转化为Resource格式:
    • classpath:bean.xml:从classpath(例如target/classes)中加载,使用ClassPathResource实现类
    • file:///src/main/config.xml:从文件系统中加载,使用UrlResource实现类
    • https://www.baidu.com/:从URL中加载,使用UrlResource实现类
    • classpath*:WEB-INF/**/*.xml:从classpath中查找,使用Ant风格的通配符,**表示零或多个目录、*表示零或多个字符(不能跨越目录),会查找所有包含该路径的资源
    • 无前缀:视具体的ApplicationContext实现类不同,可能是ClassPathResourceServletContextResource

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("a.xml");
Resource res = resourceLoader.getResource("https://www.baidu.com/");
if (res.exists() && res.isReadable()) {
try (InputStream is = res.getInputStream(); ReadableByteChannel bc = res.readableChannel();) {
// use bio or nio
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

ResourceLoaderAware接口(可选)

  • 当一个bean需要在内部使用ResourceLoaderResourcePatternResolver来方便地在类内部加载资源时,采用@Autowired才是更推荐的方式
  • 如果需要隐式注入而非显式声明,可以使bean实现ResourceLoaderAware接口
  • ResourceLoaderAware接口有一个方法setResourceLoader(ResourceLoader rl),当这个beanApplicationContext实例纳入管理时,ApplicationContext会把自己当作参数传递给这个set方法