前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解Spring中的Resource资源管理

深入理解Spring中的Resource资源管理

原创
作者头像
杨不易呀
发布2023-09-26 21:42:03
6962
发布2023-09-26 21:42:03
举报
文章被收录于专栏:杨不易呀

前言

pring中的Resource(资源)是一个抽象接口,用于表示应用程序中的各种资源,如文件、类路径资源、URL等。它提供了统一的方式来访问这些资源,无论资源位于何处,都可以通过Resource接口进行操作。Spring的Resource接口具有灵活性和可扩展性,使开发人员可以方便地加载、读取和处理各种资源,这在配置文件、模板加载和资源管理方面特别有用。这些资源可以是静态文件、动态生成的内容或外部文件等,Resource接口为访问它们提供了一致的抽象。

Resource 在 Java 当做资源使用 URL 进行表示。Spring 将对物理资源的访问方式抽象成了 Resouce, 我们可以通过 Spring 提供的接口来访问磁盘文件等数据。

image-20220102224120979
image-20220102224120979

针对不同的资源采取了不同的实现方式。

Resouce 体系结构

  • 使用 UrlResource 访问网络资源:UrlResource 来访问网络资源,也可以通过 file 前缀访问本地资源。
  • ClassPathResource 访问类加载路径下的资源ClassPathResource 用来访问类加载路径下的资源,相对于其他的 Resource 实现类,其主要优势是方便访问类加载路径里的资源,尤其对于 Web 应用,ClassPathResource 可自动搜索位于 WEB-INF/classes 下的资源文件,无须使用绝对路径访问。
  • FileSystemResource 访问文件资源系统:Spring 提供的 FileSystemResource 类用于访问文件系统资源,使用 FileSystemResource 来访问文件系统资源并没有太大的优势,因为 Java 提供的 File 类也可用于访问文件系统资源。
  • ServletContextResourceServletContext 资源的 Resource 实现,它解释相关 Web 应用程序根目录中的相对路径。
  • InputStreamResourceInputStreamResource 是给定的输入流(InputStream) 的 Resource 实现。
  • ByteArrayResource:字节数组的 Resource 实现类。通过给定的数组创建了一个 ByteArrayInputStream

资源加载策略ResourceLoad

ResourceLoader

ResourceLoader 接口提供了一个加载文件的策略。它提供了一个默认的实现类 DefaultResourceLoader。所有的应用程序上下文都实现了 ResourceLoader 接口。因此,所有的应用程序上下文都可能会获取 Resource 实例。

image-20220102230635320
image-20220102230635320

ResourceLoader 提供 classpath 下单资源文件的载入,而 classpath* 的前缀支持是在它的子接口 ResourcePatternResolver 中, ResourcePatternResolver 提供了多资源文件的载入 ResourcePatternResolver 有一个实现类 PathMatchingResourcePatternResolver

BeanDefinitionReader加载过程

BeanDefinitionReader 的作用是读取 Spring 配置文件中的内容,将其转换为 IOC 容器内部的数据结构:BeanDefinition,就是使用 ResouceLoad 将配置信息解析成一个个 BeanDefinition, 最终借助 BeanDefinitionRegistry 接口将 BeanDefinition 注册到容器当中。

BeanDefinitionReader.java 接口源代码如下:

代码语言:java
复制
/**
 * Simple interface for bean definition readers.
 * Specifies load methods with Resource and String location parameters.
 *
 * <p>Concrete bean definition readers can of course add additional
 * load and register methods for bean definitions, specific to
 * their bean definition format.
 *
 * <p>Note that a bean definition reader does not have to implement
 * this interface. It only serves as suggestion for bean definition
 * readers that want to follow standard naming conventions.
 *
 * @author Juergen Hoeller
 * @see org.springframework.core.io.Resource
 * @since 1.1
 */
public interface BeanDefinitionReader {

   /**
    * Return the bean factory to register the bean definitions with.
    * <p>The factory is exposed through the BeanDefinitionRegistry interface,
    * encapsulating the methods that are relevant for bean definition handling.
    * 返回Bean工厂以向其注册Bean定义
    */
   BeanDefinitionRegistry getRegistry();

   /**
    * Return the resource loader to use for resource locations.
    * Can be checked for the <b>ResourcePatternResolver</b> interface and cast
    * accordingly, for loading multiple resources for a given resource pattern.
    * <p>A {@code null} return value suggests that absolute resource loading
    * is not available for this bean definition reader.
    * <p>This is mainly meant to be used for importing further resources
    * from within a bean definition resource, for example via the "import"
    * tag in XML bean definitions. It is recommended, however, to apply
    * such imports relative to the defining resource; only explicit full
    * resource locations will trigger absolute resource loading.
    * <p>There is also a {@code loadBeanDefinitions(String)} method available,
    * for loading bean definitions from a resource location (or location pattern).
    * This is a convenience to avoid explicit ResourceLoader handling.
    *
    * @see #loadBeanDefinitions(String)
    * @see org.springframework.core.io.support.ResourcePatternResolver
    * <p>
    * 返回资源加载器以用于资源位置
    */
   @Nullable
   ResourceLoader getResourceLoader();

   /**
    * Return the class loader to use for bean classes.
    * <p>{@code null} suggests to not load bean classes eagerly
    * but rather to just register bean definitions with class names,
    * with the corresponding Classes to be resolved later (or never).
    * 返回用于Bean类的类加载器
    */
   @Nullable
   ClassLoader getBeanClassLoader();

   /**
    * Return the BeanNameGenerator to use for anonymous beans
    * (without explicit bean name specified).
    * 返回BeanNameGenerator用于匿名Bean(未指定显式Bean名称)
    */
   BeanNameGenerator getBeanNameGenerator();


   /**
    * Load bean definitions from the specified resource.
    * <p>
    * 从指定的资源加载bean定义
    *
    * @param resource the resource descriptor
    * @return the number of bean definitions found
    * @throws BeanDefinitionStoreException in case of loading or parsing errors
    */
   int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resources.
    *
    * @param resources the resource descriptors
    * @return the number of bean definitions found
    * @throws BeanDefinitionStoreException in case of loading or parsing errors
    */
   int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resource location.
    * <p>The location can also be a location pattern, provided that the
    * ResourceLoader of this bean definition reader is a ResourcePatternResolver.
    * <p>
    * 从指定的资源位置加载bean定义
    * 该位置也可以是位置模式,前提是此bean定义读取器的ResourceLoader是ResourcePatternResolver
    *
    * @param location the resource location, to be loaded with the ResourceLoader
    *                 (or ResourcePatternResolver) of this bean definition reader
    * @return the number of bean definitions found
    * @throws BeanDefinitionStoreException in case of loading or parsing errors
    * @see #getResourceLoader()
    * @see #loadBeanDefinitions(org.springframework.core.io.Resource)
    * @see #loadBeanDefinitions(org.springframework.core.io.Resource[])
    */
   int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resource locations.
    *
    * @param locations the resource locations, to be loaded with the ResourceLoader
    *                  (or ResourcePatternResolver) of this bean definition reader
    * @return the number of bean definitions found
    * @throws BeanDefinitionStoreException in case of loading or parsing errors
    */
   int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

Application 会适情况调用,BeanDefinitonReader 其中一个 load 方法,在 BeanDefinitionReaderload 方法当中会使用,ResourceLoad 读取资源,将解析出来的 BeanDefinition 注册到容器当中。

image-20220104212136560
image-20220104212136560
  • AbstractBeanDefinitionReader:实现了 EnvironmentCapable,提供了获取/设置环境的方法。定义了一些通用方法,使用策略模式,将一些具体方法放到子类实现。
  • XmlBeanDefinitionReader:读取 XML 文件定义的 BeanDefinition
  • PropertiesBeanDefinitionReader:可以从属性文件,ResourceProperty 对象等读取 BeanDefinition

AbstractBeanDefinitionReader

该类是实现了 BeanDefinitionReaderEnvironmentCapable 接口的抽象类,提供常见属性:工作的 bean 工厂、资源加载器、用于加载 bean 类的类加载器、环境等。该类中最核心的方法就是 loadBeanDefinitions 方法。

image-20220104212906564
image-20220104212906564

当传入的参数为资源位置数组时,进入上述方法,如果为字符串数组,则挨个遍历调用 loadBeanDefinitions(location) 方法。

关于 loadBeanDefinitions(location):根据资源加载器的不同,来处理资源路径,从而返回多个或一个资源,然后再将资源作为参数传递给 loadBeanDefinitions(resources) 方法。在该类中存在一个 loadBeanDefinitions(Resource. .. resources) 方法,该方法用于处理多个资源,归根结底,最后还是调用 loadBeanDefinitions((Resource)resource) 方法,该方法的具体实现在 XmlBeanDefinitionReader 中。

最后

本期结束咱们下次再见👋~

点赞
点赞

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Resouce 体系结构
  • 资源加载策略ResourceLoad
    • ResourceLoader
    • BeanDefinitionReader加载过程
    • AbstractBeanDefinitionReader
    • 最后
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档