Resources :获取资源文件的统一接口。
二、Resources接口主要实现类有
ClassPathResource:获取类路径下的资源文件
UrlResource:URL对应的资源,根据一个URL地址即可创建
FileSystemResource:获取文件系统里面的资源
ServletContextResource:ServletContext封装的资源,用于访问
ServletContext环境下的资源
InputStreamResource:针对输入流封装的资源
ByteArrayResource:针对于字节数封装的资源
三、Resource接口中主要定义有以下方法
exists():用于判断对应的资源是否真的存在。
isReadable():用于判断对应资源的内容是否可读。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。
isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。
getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。
getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。
getInputStream():获取当前资源代表的输入流,除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。
四、在bean中获取Resource的方式有以下四种方式
1、直接通过new各种类型的Resource来获取对应的Resource。
* ClassPathResource可以用来获取类路径下的资源
* @throws IOException
@Test
public void testClassPath() throws IOException {
Resource resource = new ClassPathResource("spring-ioc.xml");
String fileName = resource.getDescription();
System.out.println(fileName);
if (resource.isReadable()) {
//每次都会打开一个新的流
InputStream is = resource.getInputStream();
this.printContent(is);
* FileSystemResource可以用来获取文件系统里面的资源,
* 对于FileSystemResource而言我们可以获取到其对应的输出流OutputStream。
* @throws IOException
@Test
public void testFileSystem() throws IOException {
FileSystemResource resource = new FileSystemResource("D:\\test.txt");
if (resource.isReadable()) {
//FileInputStream
printContent(resource.getInputStream());
if (resource.isWritable()) {
//每次都会获取到一个新的输出流
OutputStream os = resource.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
bw.write("FileSystemResource实现类测试。");
bw.flush();
if (os != null) {
os.close();
if (bw != null) {
bw.close();
* 针对于URL进行封装的Resource,可用来从URL获取资源内容
* @throws Exception
@Test
public void testURL() throws Exception {
UrlResource resource = new UrlResource("http://www.baidu.com");
if (resource.isReadable()) {
//URLConnection对应的getInputStream()。
printContent(resource.getInputStream());
* 针对于字节数组封装的Resource,用来从字节数组获取资源内容
* @throws IOException
@Test
public void testByteArray() throws IOException {
ByteArrayResource resource = new ByteArrayResource("Hello".getBytes());
//ByteArrayInputStream()
printContent(resource.getInputStream());
* 针对于输入流的Resource,其getInputStream()方法只能被调用一次。
* @throws Exception
@Test
public void testInputStream() throws Exception {
InputStream is = new FileInputStream("D:\\test.txt");
InputStreamResource resource = new InputStreamResource(is);
//对于InputStreamResource而言,其getInputStream()方法只能调用一次,继续调用将抛出异常。
InputStream target = resource.getInputStream(); //返回的就是构件时的那个InputStream
//is将在printContent方法里面进行关闭
printContent(target);
* 输出输入流的内容
* @param is
* @throws IOException
private void printContent(InputStream is) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line=br.readLine()) != null) {
System.out.println(line);
if (is != null) {
is.close();
if (br != null) {
br.close();
2、直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。
在spring里面定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。
DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。
@Test
public void testDefaultResourceLoader() {
//ResourceLoader还可以通过实现ResourceLoaderAware接口或者使用@Autowired注解注入的方式获取
ResourceLoader loader = new DefaultResourceLoader();
Resource resource = loader.getResource("http://www.baidu.com");
System.out.println(resource instanceof UrlResource); //true
//注意这里前缀不能使用“classpath*:”,这样不能真正访问到对应的资源,exists()返回false
resource = loader.getResource("classpath:test.txt");
System.out.println(resource instanceof ClassPathResource); //true
resource = loader.getResource("test.txt");
System.out.println(resource instanceof ClassPathResource); //true
3、在bean里面获取到对应的ApplicationContext,再通过ApplicationContext的getResource(String path)方法获取对应的Resource。
因为ApplicationContext接口也继承了ResourceLoader接口,所以它的所有实现类都实现了ResourceLoader接口,都可以用来获取Resource。
对于ClassPathXmlApplicationContext而言,它在获取Resource时继承的是它的父类DefaultResourceLoader的策略。
FileSystemXmlApplicationContext也继承了DefaultResourceLoader,但是它重写了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在获取资源文件时首先也是判断指定的location是否包含“classpath:”前缀,如果包含,则把location中“classpath:”前缀后的资源从类路径下获取出来,当做一个ClassPathResource;否则,继续尝试把location封装成一个URL,返回对应的UrlResource;如果还是失败,则把location指定位置的资源当做一个FileSystemResource进行返回。
@Test
public void testContextResource() throws IOException{
//获取spring上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-ioc.xml");
//通过spring context获取Resource
Resource resource = context.getResource("classpath:spring-ioc.xml");
if (resource.isReadable()) {
//URLConnection对应的getInputStream()。
printContent(resource.getInputStream());
4、通过依赖注入的方式把Resource注入到bean中。
<bean name ="injectResource" class="com.jsun.test.springDemo.bean.InjectResource">
<!-- 采用setter注入的方式,注入resource -->
<property name="resource">
<value>classpath:spring-ioc.xml</value>
</property>
</bean>
public class InjectResource {
//声明resource以及setter方法
private Resource resource;
public void setResource(Resource resource) {
this.resource = resource;
//读取资源
public void injectResource() throws IOException{
if (resource.isReadable()) {
//URLConnection对应的getInputStream()。
printContent(resource.getInputStream());
private void printContent(InputStream is) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line=br.readLine()) != null) {
System.out.println(line);
if (is != null) {
is.close();
if (br != null) {
br.close();
@Test
public void testInjectResource() throws IOException{
InjectResource injectResource = super.getBean("injectResource");
injectResource.injectResource();
作者:glowd
原文:https://blog.csdn.net/zengqiang1/article/details/54601235
版权声明:本文为博主原创文章,转载请附上博文链接!
Spring探索:既生@Resource,何生@Autowired?
提到Spring依赖注入,大家最先想到应该是@Resource和@Autowired,很多文章只是讲解了功能上的区别,对于Spring为什么要支持两个这么类似的注解却未提到,属于知其然而不知其所以然。不知大家在使用这两个注解的时候有没有想过,@Resource又支持名字又支持类型,还要@Autowired干嘛,难道是Spring官方没事做了?
13207
Spring源码学习:一篇搞懂@Autowire和@Resource注解的区别
最近在刷到很多文章讲解Spring IOC依赖注入时@Autowire和@Resource注解的区别,不同的文章总结出来的点有异同,所以还是看源码自己总结一下其两者的区别,及其用法。
更方便Spring存储和读取对象,五大类注解、@Bean、@Autowired、@Resource
更方便Spring存储和读取对象,五大类注解、@Bean、@Autowired、@Resource
Spring中的Autowired、Qualifier、Resource注解详解
使用Spring系列的框架对这三个注解肯定都不会陌生,这三个注解有一个特性,就是用于属性注入,说白了点就是将Spring容器中的对象取出来,这样我们才可以使用,那么这三者到底是什么关系,又有什么区别呢?
Spring 为什么引入资源管理?
Java 中有各种各样的资源,资源的位置包括本地文件系统、网络、类路径等,资源的形式可以包括文件、二进制流、字节流等,针对不同的资源又有不同的加载形式。
Spring 源码阅读 44:@Resource 注解的处理
本文分析了 CommonAnnotationBeanPostProcessor 后处理器处理`@Resource`等注解的解析和注入的原理。
Spring 源码阅读 01:Resource 资源抽象
在 Spring 的核心源码中,`Resource` 接口定义了 Spring 对底层资源访问的抽象,通过实现 Resource 接口,我们可以开发各种资源的访问能力。
阿里云最有价值专家,简称 MVP(Most Valuable Professional),是专注于帮助他人充分了解和使用阿里云技术的意见领袖阿里云 MVP 奖项为我们提供了这样一个机会,向杰出的意见领袖表示感谢,更希望通过 MVP 将开发者的声音反映到我们的技术路线图上。