spring资源访问接口和资源加载接口

时间:2023-03-09 06:55:07
spring资源访问接口和资源加载接口

spring 资源访问接口

JDK提供的资源访问类,如java.net.URL、File等,不能很好地满足各种资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类。

鉴于此,spring设计了Resource接口,该接口拥有对应不同资源类型的实现类,比如ClassPathResource以类路径的方式访问资源;ServletContextResource以相对于Web应用根目录的方式访问资源。

    public static void main(String[] args) throws IOException {
        ClassPathResource resource1 = new ClassPathResource("config/my.xml");
        ClassPathResource resource2 = new ClassPathResource("com/test/Driver.class");
        File file = resource1.getFile();
        System.out.println(file);
        file = resource2.getFile();
        System.out.println(file);
        /**
         * 使用Resource操作文件时,如果资源文件在jar包中,因为jar本来就是一个文件,
         * 所以不能使用Resource的getFile()方法获取这个文件中的文件,会抛出FileNotFoundException。
         * 但可以使用Resource的getInputStream()方法获取jar包中的文件。
         */
        InputStream inputStream1 = resource1.getInputStream();
        InputStream inputStream2 = resource2.getInputStream();
    } 

spring资源加载接口

为了访问不同类型的资源,必须使用对应的Resource实现类;为此spring提供了资源加载机制,不再需要显示使用Resource实现类,通过资源地址的前缀自动使用不同的Resource实现,并且还支持通配符。

资源加载接口ResourceLoader采用了策略模式,可以通过传入资源地址的前缀,自动选择适合的实现类。

1、资源加载的使用

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;

public class MyTest {
    public static void main(String[] args) throws IOException {
        ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
        // 资源地址的前缀为classpath,所以会自动使用ClassPathResource去classpath下去访问文件
        Resource[] resources = resourceLoader.getResources("classpath*:*.xml");
        for (int i = 0; resources != null && i < resources.length; i++) {
            System.out.println(resources[i].getFilename());
        }
        System.out.println("方法结束");
    }
}

a.资源地址可以使用的前缀有:1. classpath:  2. classpath*:   3.file:   4.http://    5.ftp://   6.没有前缀

b.资源地址支持三种通配符:?匹配文件名中的一个字符;* 匹配文件名中任意字符;** 匹配多层路径

c."classpath*:"和"classpath:"的区别
classpath只在本项目的classpath中寻找资源,classpath*不只在本项目的classpath中寻找资源,还会到本项目依赖的jar包里寻找资源,示例项目:https://files-cdn.cnblogs.com/files/Mike_Chang/parent.rar

2、分析资源加载机制

a、资源加载的最上层接口是ResourceLoader

package org.springframework.core.io;

public interface ResourceLoader {
    // 根据classpath:查询资源
    String CLASSPATH_URL_PREFIX = "classpath:";

    Resource getResource(String var1);

    ClassLoader getClassLoader();
}

b、ResourcePatternResolver接口扩展了

package org.springframework.core.io.support;

import java.io.IOException;

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

public interface ResourcePatternResolver extends ResourceLoader {
    // 根据classpath*:查询资源
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
    // 支持通配符的资源路径表达式
    Resource[] getResources(String locationPattern) throws IOException;
}

c.PathMatchingResourcePatternResolver是一个真正的实现类

public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
    // 实现了上面两个接口
}