【Spring | 资源处理扩展】
作者:mmseoamin日期:2023-12-25

上文讲了 【Spring | 资源处理 】

本文讲一下resource的扩展接口相关

资源处理扩展

  • ResourceLoader 接口
    • 定义
    • 图解
    • 示例
    • 策略
    • ResourcePatternResolver接口
    • ResourceLoaderAware接口
    • 资源依赖
      • 定义
      • value注解加载
      • 加载多资源

        ResourceLoader 接口


        ResourceLoader 接口用于加载 Resource 对象。

        定义


        定义如下:

        public interface ResourceLoader {
        	Resource getResource(String location);
        	ClassLoader getClassLoader();
        }
        

          Spring 中,所有的 ApplicationContext 都实现了 ResourceLoader 接口。因此,所有 ApplicationContext 都可以通过 getResource() 方法获取 Resource实例。

        图解


        图解如下:

        在这里插入图片描述

        示例


        示例如下:

        // 
        Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
        // 
        Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
        //
        Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
        //
        Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
        

        策略


        Spring根据各种位置路径加载资源的策略如下:

        字首样例描述
        classpath:classpath:com/myapp/config.xml从类路径加载
        file:file:///data/config.xml以URL形式从文件系统加载
        http:http://myserver/logo.png以URL形式加载
        /data/config.xml取决于底层ApplicationContext

        ResourcePatternResolver接口


          ResourcePatternResolver接口是 ResourceLoader接口的扩展,它的作用是定义策略,根据位置模式解析Resource对象。

        public interface ResourcePatternResolver extends ResourceLoader {
        	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
        	Resource[] getResources(String locationPattern) throws IOException;
        }
        

          由上文示例可知,该接口还为类路径中的所有匹配资源定义了一个特殊的classpath*:resource前缀。请注意,在这种情况下,资源位置应该是一个没有占位符的路径 — 例如,类路径中的classpath*:/config/beans.xml.JAR文件或不同目录可以包含多个具有相同路径和相同名称的文件。

          PathMatchingResourcePatternResolver是一个独立的实现,可以在ApplicationContext外部使用,也可以被ResourceArrayPropertyEditor用于填充Resource[]bean属性。PathMatchingResourcePatternResolver 能够将指定的资源位置路径解析为一个或多个匹配的Resource对象。

        🔔 注:

          任何标准ApplicationContext中的默认ResourceLoader实际上都是PathMatchingResourcePatternResolver的一个实例,它实现了ResourcePatternResolver接口。

        ResourceLoaderAware接口


          ResourceLoaderAware 接口是一个特殊的回调接口,用于标记提供ResourceLoader引用的对象。

        定义如下:

        public interface ResourceLoaderAware {
        	void setResourceLoader(ResourceLoader resourceLoader);
        }
        

          当一个类实现ResourceLoaderAware并部署到ApplicationContext中(作为 Spring 管理的 bean)时,它会被ApplicationContext识别为ResourceLoaderAware,然后,ApplicationContext会调用setResourceLoader(ResourceLoader),将自身作为参数提供(请记住,Spring 中的)所有ApplicationContext都实现ResourceLoader接口)。

          由于ApplicationContext是一个ResourceLoader,该bean还可以实现ApplicationContextAware接口并直接使用提供的ApplicationContext来加载资源。但是,一般来说,如果您只需要这些,最好使用专用的接口。该代码将仅连接到资源加载ResourceLoader接口(可以被视为实用程序接口),而不是耦合到整个 SpringApplicationContext接口。

          在应用程序中,还可以使用ResourceLoader自动装配作为实现ResourceLoaderAware接口的替代方法。传统的构造函数和byType自动装配模式能够分别为构造函数参数或setter方法参数提供ResourceLoader。以获得更大的灵活性(包括自动装配字段在这种情况下,会自动ResourceLoader连接到需要ResourceLoader类型的字段、构造函数参数或方法参数中,只需相关字段、构造函数或方法带有@Autowired注解即可。

        🔔 注:

          要为包含通配符或使用特殊类路径*:Resource前缀的资源路径加载一个或多个Resource对象,请考虑将ResourcePatternResolver的实例自动连接到应用程序组件中,而不是ResourceLoader。

        资源依赖


        定义


          如果bean本身要通过某种动态过程来确定并提供资源路径,那么bean可以使用ResourceLoader或ResourcePatternResolver接口来加载资源。例如,考虑加载某种模板,其中需要的特定资源取决于用户的角色。如果资源是静态的的,完全消除ResourceLoader接口(或ResourcePatternResolver接口)的使用,让bean公开它需要的Resource属性,并希望将它们注入其中是有意义的。

          使注入这些属性变得简单的原因是所有应用程序下面都注册并使用一个特殊的JavaBeans PropertyEditor,它可以将String路径转换为Resource对象。例如,下面的MyBean类有一个Resource类型的模板属性。

        public class MyBean {
        	private Resource template;
        	public setTemplate(Resource template) {
        		this.template = template;
        	}
        	// ...
        }
        

          请注意,配置中引用的模板资源路径本身没有远端,因为应用程序下游将使用,ResourceLoader资源本身将根据需要通过ClassPathResource,FileSystemResource或 ServletContextResource 加载,取决于具体下游的目的类型。

          如果需要强制显示使用特定的资源类型,则可以使用导出。以下两个示例如何强制使用ClassPathResource和UrlResource(后者用于访问文件系统文件)。

        
        
        

        value注解加载


        可以通过@Value注解加载资源文件myTemplate.txt,示例如下:

        @Component
        public class MyBean {
        	private final Resource template;
        	public MyBean(@Value("${template.path}") Resource template) {
        		this.template = template;
        	}
        	// ...
        }
        

          Spring的PropertyEditor会根据资源文件的路径字符串,加载Resource对象,把其注入到MyBean的构造方法。

        加载多资源


        如果想要加载多个资源文件,可以使用classpath*:出口,例如:classpath*:/config/templates/*.txt。

        @Component
        public class MyBean {
        	private final Resource[] templates;
        	public MyBean(@Value("${templates.path}") Resource[] templates) {
        		this.templates = templates;
        	}
        	// ...
        }
        

        在这里插入图片描述

          如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论
          你的支持就是我✍️创作的动力!					  💞💞💞
        

        参考:

        spring - Resource 官方文档