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

简介: 深入理解Spring中的Resource资源管理

前言


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


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


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




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 实例。

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




BeanDefinitionReader加载过程


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

BeanDefinitionReader.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 注册到容器当中。

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




AbstractBeanDefinitionReader


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

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

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





最后


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

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

相关文章
|
2月前
|
Java 数据库 Spring
【Spring】资源操作管理:Resource、ResourceLoader、ResourceLoaderAware;
【Spring】资源操作管理:Resource、ResourceLoader、ResourceLoaderAware;
76 1
|
2月前
|
Java Spring 容器
Spring中@Autowired和@Resource注解异同点
Spring中@Autowired和@Resource注解异同点
45 0
|
2月前
|
算法 程序员 数据库连接
深入探索C++中的RAII原则:资源管理的艺术 (In-Depth Exploration of RAII in C++: The Art of Resource Management)...
深入探索C++中的RAII原则:资源管理的艺术 (In-Depth Exploration of RAII in C++: The Art of Resource Management)...
62 2
|
2月前
|
安全 Java 开发者
Spring依赖注入大揭秘:@Autowired、@Qualifier和@Resource的区别与应用
Spring依赖注入大揭秘:@Autowired、@Qualifier和@Resource的区别与应用
103 0
|
2月前
|
Java Spring
spring注解@Autowired、@Resource说明
spring注解@Autowired、@Resource说明
|
2月前
|
Java 编译器 Spring
Spring中@Autowired和@Resource的区别
Spring中@Autowired和@Resource的区别
122 0
|
2月前
|
Java Spring 容器
[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效
[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效
|
2月前
|
Java Spring 容器
Spring自动装配【Bean的作用域、@Autowried、@Resource】
Spring自动装配【Bean的作用域、@Autowried、@Resource】
|
8月前
|
存储 Java Spring
Spring框架中的Resource接口是什么,以及它在加载和访问资源时的关键作用
使用 Resource 加载资源 要使用 Resource 接口加载资源,首先需要获取一个 ResourceLoader 实例,通常可以通过依赖注入来获得。接下来,您可以使用 ResourceLoader 来获取 Resource 对象,然后使用它来访问资源的内容。
|
8月前
|
Java Spring 容器
Spring中@Autowired与@Resource自动注入实现原理
Spring中@Autowired与@Resource自动注入实现原理
70 0