【小家Spring】资源访问利器---Spring使用ResourceLoader接口便捷的获取资源(ResourcePatternResolver、ResourceLoaderAware)(中)

简介: 【小家Spring】资源访问利器---Spring使用ResourceLoader接口便捷的获取资源(ResourcePatternResolver、ResourceLoaderAware)(中)


AbstractRefreshableWebApplicationContext


下面的子类都是和web相关了。所以就和ServletContext相关嘛~~~


// @since 1.1.3
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext
    implements ConfigurableWebApplicationContext, ThemeSource {
    ...
  @Override
  protected Resource getResourceByPath(String path) {
    Assert.state(this.servletContext != null, "No ServletContext available");
    return new ServletContextResource(this.servletContext, path);
  }
  // ServletContextResourcePatternResolver是PathMatchingResourcePatternResolver的子类 
  @Override
  protected ResourcePatternResolver getResourcePatternResolver() {
    return new ServletContextResourcePatternResolver(this);
  }
  ...
}


XmlWebApplicationContext


他没有自己的实现,但我们可议简单的回味一下它的类

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
  /** Default config location for the root context */
  public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
  /** Default prefix for building a config location for a namespace */
  public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
  /** Default suffix for building a config location for a namespace */
  public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
  ...
}



AnnotationConfigWebApplicationContext

它是注解驱动的,所以也就没有必要冲洗方法喽 @since 3.0


GenericApplicationContext

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
  ...
  // 它重写一个逻辑都是:加入调用者自己指定了resourceLoader,那就以调用者为准
  @Override
  public Resource getResource(String location) {
    if (this.resourceLoader != null) {
      return this.resourceLoader.getResource(location);
    }
    return super.getResource(location);
  }
  @Override
  public Resource[] getResources(String locationPattern) throws IOException {
    if (this.resourceLoader instanceof ResourcePatternResolver) {
      return ((ResourcePatternResolver) this.resourceLoader).getResources(locationPattern);
    }
    return super.getResources(locationPattern);
  }
  ...
}


image.png

如图的几个子类。除了带web的重写了一下(使用ServletContextResource和ServletContextResourcePatternResolver),其余子类都没有重写的必要~~~~


子接口 ResourcePatternResolver 解析


上面已经介绍了ResourceLoader的实现,那么接下来针对于子接口进一步讨论。其实它使用得反而更加的广泛,也更加的强大。从名字中可以看出,它支持Pattern,支持正则的模式匹配,非常的强大~~~


用于解析资源文件的策略接口,其特殊的地方在于,它应该提供带有*号这种通配符的资源路径。 此接口是ResourceLoader接口的拓展接口。


// @since 1.0.2 显然它出现的时机晚于ResourceLoader接口
public interface ResourcePatternResolver extends ResourceLoader {
  // 与ResourceLoader中classpath不同的地方在于,此前缀会在所有的JAR包的根目录下搜索指定文件。  非常的强大
  String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
  // 返回指定路径下所有的资源对象。
  // 返回的对象数组有Set的语义,也就是说,`对于同一个资源,只返回一个资源对象`
  Resource[] getResources(String locationPattern) throws IOException;
}


先来个Demo,简单的感受下classpath*的威力:


     public static void main(String[] args) throws IOException {
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("classpath:META-INF/spring.factories");
        // 因为`classpath:`只在本工程内查找,所以肯定找不到 spring.factories
        System.out.println(resource.exists()); //false
        PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources("classpath*:META-INF/spring.factories");
        // 它会去找所有的jar包的类路径开始查找,所以现在是可议找到多个的~~~
        System.out.println(resources.length); //2
        System.out.println(Arrays.asList(resources));
        //[URL [jar:file:/E:/repository/org/springframework/spring-beans/5.0.6.RELEASE/spring-beans-5.0.6.RELEASE.jar!/META-INF/spring.factories],
        //URL [jar:file:/E:/repository/org/springframework/spring-test/5.0.6.RELEASE/spring-test-5.0.6.RELEASE.jar!/META-INF/spring.factories]]
        // 还能使用Ant风格进行匹配~~~  太强大了:
        resources = resourcePatternResolver.getResources("classpath*:META-INF/*.factories");
        System.out.println(resources); // 能匹配上所有了路径下,`META-INF/*.factories`匹配上的所有文件
        resources = resourcePatternResolver.getResources("classpath*:com/fsx/**/*.class");
        System.out.println(resources.length); //42 相当于把我当前项目所有的类都拿出来了
    }


image.png



相关文章
|
1天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
|
1天前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
13 2
|
1天前
|
Java 开发者 Spring
Spring Boot中的资源文件属性配置
【4月更文挑战第28天】在Spring Boot应用程序中,配置文件是管理应用程序行为的重要组成部分。资源文件属性配置允许开发者在不重新编译代码的情况下,对应用程序进行灵活地配置和调整。本篇博客将介绍Spring Boot中资源文件属性配置的基本概念,并通过实际示例展示如何利用这一功能。
25 1
|
1天前
|
Java 数据库连接 数据库
spring+mybatis_编写一个简单的增删改查接口
spring+mybatis_编写一个简单的增删改查接口
17 2
|
1天前
|
算法 NoSQL Java
限流艺术:Spring Boot接口限流的实用指南
限流艺术:Spring Boot接口限流的实用指南
98 0
限流艺术:Spring Boot接口限流的实用指南
|
1天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
56 0
|
1天前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
138 0
|
1天前
|
存储 JSON Java
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
48 2
|
1天前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
|
1天前
|
前端开发 Java 应用服务中间件
Springboot对MVC、tomcat扩展配置
Springboot对MVC、tomcat扩展配置