spring资源操作

news2024/9/23 2:55:31

spring资源操作(Resource)

Java的标准java.net.URL类和各种URL前缀的处理标准处理程序无法满足所有对low-level资源的访问,比如:没有标准优化的URL实现可用于访问需要从类路径或相对于ServletContext获取的资源。并缺少某些Spring所需要的功能。如检测某资源是否存在等。而Spring的Resource声明了访问low-level资源的能力。

Spring Resource

Resource接口

Resource接口是Spring资源访问策略的抽象,它本身不提供任何资源访问实现,具体的资源访问由该接口的实现类完成(每一个实现类代码表一种资源访问策略)。Resource一般包含这些实现类:UrlResourceClassPathResourceFileSystemResourceServletContextResourceInputStreamResourceByteArrayResource

UrlResource访问网络资源

Resource的一个实现类,用来访问网络资源,它支持URL的绝对路径
http:该前缀用于访问基于HTTP协议的网络资源。
ftp:该前缀用于访问基于FTP协议的网络资源
file:该前缀用于从文件系统中读取资源。

示例
    //UrlResource访问网络资源
    public class UrlResourceDemo {
        public static void loadUrlResource(String path){
            //创建Resource实现类的对象UrlResource
            try {
                UrlResource url = new UrlResource(path);
                //获取资源信息
                System.out.println("url.getURL()" + url.getURL());
                System.out.println("url.getFilename() = " + url.getFilename());
                System.out.println("url.getDescription() = " + url.getDescription());
                System.out.println("url.getInputStream() = " + url.getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        public static void main(String[] args) {
            //http前缀
            UrlResourceDemo.loadUrlResource("http://www.baidu.com");
            /*
            url.getURL()http://www.baidu.com
            url.getFilename() =
            url.getDescription() = URL [http://www.baidu.com]
            url.getInputStream() = sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@7591083d
            * */

            //file前缀,下面的写法需要注意文件要放在根路径下(spring6),也可以写如绝对路径
            loadUrlResource("file:louis.txt");
            /*
            * url.getURL()file:louis.txt
            url.getFilename() = louis.txt
            url.getDescription() = URL [file:louis.txt]
            url.getInputStream() = java.io.BufferedInputStream@7eda2dbb
            * */
        }
    }

ClassPathResource访问路径下资源

ClassPathResource用来访问类加载路径下的资源,相对于其他的Resource实现类,其主要优势是方便访问类加载路径里的资源,尤其对于web应用,ClassPathResource可自动搜索位于classes下的资源文件,无需使用绝对路径

示例
package com.louis.resource;

import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author XRY
 * @date 2023年06月28日18:40
 */
//访问类路劲下的资源
public class ClassPathResourceDemo {
    public static void loadClassPathResource(String url){
        //创建对象
        ClassPathResource classPathResource = new ClassPathResource(url);
        System.out.println("classPathResource.getFilename() = " + classPathResource.getFilename());
        System.out.println("classPathResource.getDescription() = " + classPathResource.getDescription());
        //获取文件内容
        try {
            InputStream inputStream = classPathResource.getInputStream();
            byte[] b = new byte[1024];
            int len = 0;
            while((len = inputStream.read(b)) != -1){
                System.out.println(new String(b, 0, len));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //是相对路径,可以放在resources下
        loadClassPathResource("louis.txt");
        /*
        * classPathResource.getFilename() = louis.txt
          classPathResource.getDescription() = class path resource [louis.txt]
          Hi,louis
        * */
    }
}

FileSystemResource访问文件系统资源

Spring提供的FileSystemResource类用于访问文件系统资源,使用FileSystemResource来访问文件系统资源并没有太大的优势,因为java提供的File类也可以用于访问文件系统资源。

示例
public class FileSystemResourceDemo {
    public static void  loadFileResource(String path){
        //创建对象
        FileSystemResource fileResource = new FileSystemResource(path);
        System.out.println("fileResource.getFilename() = " + fileResource.getFilename());
        System.out.println("fileResource.getDescription() = " + fileResource.getDescription());
        //创建输入流对象
        try {
            InputStream inputStream = fileResource.getInputStream();
            byte[] bytes = new byte[1024];
            int len = 0;
            while((len=inputStream.read(bytes))!=-1){
                System.out.println(new String(bytes, 0, len));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //相对路径或绝对路径
        loadFileResource("C:\\Users\\XRY\\Desktop\\text.txt");
        /*
        *   fileResource.getFilename() = text.txt
            fileResource.getDescription() = file [C:\Users\XRY\Desktop\text.txt]
            测试fileSystemResource
        * */
    }
}

在这里插入图片描述

ServletContextResource

这是ServletContext资源的Resource实现,它解释相关Web应用程序根目录中的相对路径,它始终支持流(stream)访问和URL访问,但只有在扩展web应用程序存档且资源实际位于文件系统上时才允许java的io,File访问,无论他是在文件系统上扩展还是直接从JAR或其他地方访问,实际上都是依赖Servlet容器。

InputStreamResource

InputStreamResource是给定的输入流InputStream的Resource实现,它的使用场景在没有特定的资源实现的时候使用(感觉和@Component的使用场景很相似)。与其他Resource实现相比,这是已经打开资源的描述符,因此,它的isOpen()方法返回true,如果需要将资源描述符保留在某处或者需要多次读取流,建议不要使用。

ByteArrayResource

字节数组的Resource实现类。通过给定的数组创建一个ByteArrayInputStream。它对于从任何给定的字节数组加载内容非常有用,而无需求助于单次使用的InoutStreamResource.


ResourceLoader接口

Spring ResourceLoader概述

ResourceLoader:该接口实现类的实例可以获得一个Resource实例
ResourceLoaderAware:该接口实现类的实例将获得一个ResourceLoader的引用

ResourceLoader

在ResourceLoader接口主要定义了一个方法:
getResource(String location):该接口,用于返回一个Resource实例。

ApplicationContext实现类都实现ResourceLoader接口,因此ApplicationContext可直接获取Resource实例。

示例
@Test
public void testClassPathXmlApplicationContext() {
    ApplicationContext context = new ClassPathXmlApplicationContext();
    Resource resources = context.getResource("louis.txt");
    System.out.println(resources.getFilename());
    /*
    * louis.txt
    * */
}


@Test
public void testFileSystemApplicationContext(){
    ApplicationContext context = new FileSystemXmlApplicationContext();
    Resource resource = context.getResource("louis.text");
    System.out.println(resource.getFilename());
    /*
    * louis.text
    * */
}

Spring采用ApplicationContext相同的策略来访问资源,如果ApplicationContext是FileSystemApplicationContext,返回的就是FileSystemResource实例,如果ApplicationContext是ClassPathXmlApplicationContext,返回的就是ClassPathResource

总结:

当spring应用需要进行资源访问时,实际上并不需要直接使用Resource实现类,而是调用ResourceLoader实例的getResource()方法获取资源,ResourceLoader将会负责选择Resource实现类,也就是确定具体的资源访问策略,从而将应用程序和具体的资源访问策略分开来,另外,使用ApplicationContext访问资源时,可通过不同前缀指定强制使用指定的ClassPathResource、FileSystemResource等实现类。

ResourceLoaderAware

ResourceLoaderAware接口实现类的实例将获得一个ResourceLoader的引用,ResourceLoaderAware接口也提供了一个setResourceLoader()方法,该方法由spring容器负责调用,spring容器会将一个ResourceLoader对象作为该方法的参数传入。
如果把实现ResourceLoaderAware接口的Bean类部署在Spring容器中,Spring容器会将自身当成ResourceLoader作为setResourceLoader()方法的参数传入。由于ApplicationContext的实现类都实现了ResourceLoader接口,Spring容器自身完全可作为ResourceLoader使用。

测试通过get、set方法创建的ResourceLoader和Spring传入的ResourceLoader是否为同一对象

自主创建
public class TestResourceLoaderAware implements ResourceLoaderAware {
    private ResourceLoader resourceLoader;


    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public ResourceLoader getResourceLoader() {
        return this.resourceLoader;
    }
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="testResourceLoaderAware" class="com.louis.resourceloaderaware.TestResourceLoaderAware"></bean>
</beans>
测试
@Test
public void testAware(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    TestResourceLoaderAware loaderAware = applicationContext.getBean("testResourceLoaderAware", TestResourceLoaderAware.class);
    ResourceLoader resourceLoader = loaderAware.getResourceLoader();
    System.out.println(resourceLoader == applicationContext);
    /*true*/
}

Resource作为属性

Bean实例需要访问资源,有如下的两种方式:

1、代码中获取Resource实例
2、使用依赖注入

对于第一种方式,当程序获取Resource实例时,总需要提供Resource所在的位置,这意味着资源所有的物理位置将被耦合到代码中,如果资源位置发生改变,则必须改写程序,因此,通常建议使用方式二,让Sprig为Bean实例依赖注入资源。

Spring为Bean实例依赖注入资源

步骤
1、创建ResourceBean类
public class ResourceBean {
    private Resource resource;

    public Resource getResource() {
        return resource;
    }

    public void setResource(Resource resource) {
        this.resource = resource;
    }

    public void parse(){
        System.out.println(resource.getFilename());
        System.out.println(resource.getDescription());
    }
}
2、使用配置文件(bean-di.xml)引入资源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <bean id="resourceBean" class="com.louis.di.ResourceBean">
           <property name="resource" value="louis.txt"></property>
       </bean>
</beans>
3、测试
public class TestResourceBean {
    @Test
    public void testResourceBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean-di.xml");
        ResourceBean resource = context.getBean("resourceBean", ResourceBean.class);
        resource.parse();
       /*
        * louis.txt
          class path resource [louis.txt]
        * */
    }
}

应用程序上下文和资源路径

概述

不管以怎样的方式创建ApplicationContext实例,都需要为Application指定配置文件,Spring允许使用一份或多分XML配置文件,当程序创建ApplicationContext实例时,通常也是以Resource的方式访问配置文件,所以ApplicationContext完全支持ClassPathResource、FileSystemResource、ServletContextResource等资源的访问方式。

ApplicationContext确定资源访问策略通常有两种方式

  • 使用ApplicationContext实现类指定访问路径
  • 使用前缀指定访问路径

ApplicationContext实现类执行访问路径

创建ApplicationContext对象时,通常可以实现如下实现类:

  • ClassPathXMLApplicationContext:对应使用ClassPathResource进行资源访问
  • FileSystemXmlApplicationCOntext:对应使用FileSystemResource进行资源访问
  • XmlWebApplicationContext:对应使用ServletContextResource进行资源访问

当使用ApplicationContext不同实现类时,就意味着Spring使用响应的资源访问策略,之前写的就是这种方式。

使用前缀指定访问路径

测试类

public class TestDemo {
    public static void main(String[] args){
        //classpath:就表示通过前缀查找类路径下的资源
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean-prefix.xml");
        Resource resource = context.getResource("louis.txt");
        System.out.println("resource =  " + resource.getDescription());
        /*resource =  class path resource [louis.txt]*/
    }
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="prefixResource" class="com.louis.prefix.TestDemo"></bean>
</beans>
classpath通配符使用

classpath*:前缀提供了加载多个XMl配置文件的能力,当使用classpath*:前缀来指定XML配置文件时,系统将搜索类加载路径,找到与文件名匹配的文件,分别加载文件中的配置定义,最后合并成一个ApplicationContext

ApplicationContext context = new ClassPathXmlApplicationContext("classpath\*:bean.xml");

如果不采用classpath*:前缀,而是改为classpath:前缀,Spring则只加载第一个符合条件的XML文件

注意:

classpath*:前缀仅对ApplicationContext有效,实际情况是,创建ApplicationContext时,分别访问多个配置文件(通过ClassLoader的getResource方法实现)。因此,classpath*:前缀不可用于Resource。

通配符其他使用

一次加载多个配置文件的方式:指定配置文件时使用通配符

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean*.xml");

Spring允许将classpath*:前缀和通配符结合使用

ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:bean*.xml");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/797322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java发送短信验证码《工具类》

1、短信的签名 就是申请短信服务的平台是做什么的&#xff1f; 2、短信的模板 尊敬的${name}&#xff0c;感谢您的注册&#xff0c;您的MT4账号&#xff1a;${account}&#xff0c;密码&#xff1a;${password},请到官网下载软件。3、发送信息 pom.xml <!-- 阿里…

软件模块管理权限的设置

在应用软件中&#xff0c;通常将软件的功能分为若干个子程序&#xff0c;通过主程序调用。那么&#xff0c;通过众多客户来 说明&#xff0c;如果设置各人的权限呢? 一、模板的权限 .主程序Main.EXE&#xff0c;通过菜单调用几十个子程序。如&#xff1a; 1、主程序Main.EXE&a…

Redis学习1--Redis简介与基础数据类型操作

1、什么是Redis? Remote Dictionary Server&#xff0c;远程词典服务器&#xff0c;是一个基于内存的键值型NoSQL数据库 特点&#xff1a; 键值&#xff08;key-value&#xff09;型&#xff0c;value支持多种不同数据结构&#xff0c;功能丰富单线程&#xff0c;每个命令具…

Winform使用PictureBox控件显示图片并且自适应

一.首先我们只需要在项目文件中的/bin/Debug 下面创建一个文件夹保存你的照片。我这里文件夹名字叫Resources.。如图&#xff1a; 二. 然后我们把我们的照片放入Resources文件夹中即可。如图&#xff1a; 三.在构造器中添加picturebox控件。如图&#xff1a; 四.我们到初始化代…

Mybatis学习笔记教程

Mybatis-9.28 环境&#xff1a; JDK1.8Mysql 5.7maven 3.6.1IDEA 回顾&#xff1a; JDBCMysqlJava基础MavenJunit SSM框架&#xff1a;配置文件的。 最好的方式&#xff1a;看官网文档&#xff1b; 1、简介 1.1、什么是Mybatis MyBatis 是一款优秀的持久层框架它支持定制…

智能驾驶中的数据标注

目前&#xff0c;各大自动驾驶汽车制造商都在通过获取高质量的训练数据最大化其数据资产的投入产出比。在海量的智能驾驶数据面前&#xff0c;如何让每个数据都有存在意义&#xff1f;从《数字商业时代》对澳鹏Appen(中国)高级产品总监张童皓的采访中&#xff0c;你或许能找到一…

【Leetcode】二叉树进阶面试题

文章目录 二叉树创建字符串二叉树分层遍历&#xff08;从前开始&#xff09;二叉树分层遍历&#xff08;从后开始&#xff09;二叉树的最近公共祖先二叉搜索树与双向链表从前序与中序遍历序列构造二叉树从中序与后序遍历序列构造二叉树二叉树的前序遍历&#xff08;非递归&…

数仓学习---16、可视化报表(Superset)

星光下的赶路人star的个人主页 真正的才智是刚毅的志向 文章目录 1、Superset入门1.1 Superset概述1.2 环境说明 2、Superset安装2.1 安装Python环境2.1.1 安装Miniconda2.1.2 创建Python3.7 环境 2.2 Superset部署2.2.1 安装依赖2.2.2 安装Superset2.2.3 启动Superset2.2.4 Su…

黑客工具大全(网络安全)

1.Nmap 它是网络管理员必用的软件之一&#xff0c;以及用以评估网络系统安全。正如大多数被用于网络安全的工具&#xff0c;nmap 也是不少黑客及骇客&#xff08;又称脚本小子&#xff09;爱用的工具 。 系统管理员可以利用nmap来探测工作环境中未经批准使用的服务器&#xf…

性能如何通过分析后台资源确定瓶颈之磁盘网络

目录 影响性能的因素 磁盘 网络 应用程序-上下文切换 通俗的判断性能的好坏 影响性能的因素 磁盘 %Disk time指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。--磁盘的繁忙程度&#xff0c;一般不超过80%。 Disk reads&#xff08;writes&#xff09;b…

Linux-文件管理

1.文件管理概述 1.Bash Shell对文件进行管理 谈到Linux文件管理&#xff0c;首先我们需要了解的就是&#xff0c;我们要对文件做些什么事情&#xff1f; 其实无非就是对一个文件进行、创建、复制、移动、查看、编辑、压缩、查找、删除、等等 例如 : 当我们想修改系统的主机名…

momentjs

年月日 moment(date).format(YYYY-MM-DD) 年月日时间 moment(date).format(YYYY-MM-DD HH-MM-SS) 中文XX月XX日.moment(date).format(MMMDo)

A comprehensive survey on segment anything model for vision and beyond

视觉分割大模型的过去、现在和未来&#xff01;SAM最新综述来了&#xff01;今天自动驾驶之心很荣幸邀请到Garfield来分享视觉SAM分割大模型的最新综述&#xff0c;如果您有相关工作需要分享&#xff0c;https://mp.weixin.qq.com/s/-_QFvxBGzFpAgVGF-t-XRgSegment Anything Mo…

从游戏中理解《重构的时机和方法》(文末送书)

本次推荐的书籍是《重构的时机和方法》&#xff0c;该文是由法国克里斯蒂安克劳森(Christian Clausen) 著作&#xff0c;由郭涛翻译。 重构的时机和方法 寄语译者/本书作者原文作者群英推荐目录自我感受好书哪里来&#x1f929;免费的书籍哪里来&#x1f929; 寄语 作者寄语&a…

Tencent : TBDS

序言 腾讯大数据处理套件&#xff08;Tencent Big Data Suite&#xff0c;TBDS&#xff09;是基于腾讯多年海量数据处理经验&#xff0c;对外提供的可靠、安全、易用的大数据处理平台。您可以借助 TBDS 在公有云、私有云、非云化环境&#xff0c;根据不同数据处理需求选择合适…

栈和队列模拟实现(C++)

文章目录 1.deque的认识1.1介绍2.图析 2.stack模拟实现3.queue模拟实现4.优先级队列模拟实现4.1介绍4.2例题4.3模拟实现 5.测试函数 1.deque的认识 1.1介绍 双端队列 Deque(通常读作“deck”)是double-ended queue的不规则首字母缩写。双端队列是动态长度的序列容器&#xff0…

MySQL多表查询(联合查询、连接查询、子查询)

目录 多表联合查询 联合查询类型 多表连接查询 多表查询的分类 交叉查询&#xff08;笛卡尔积&#xff09; 内连接查询 外连接查询 自连接查询 子查询规则 子查询的分类 子查询的不同结果 EXISTS和NOT EXISTS 子查询应用的不同位置 不同外部语句的子查询应用情况…

spring boot--自动化注入组件原理、内嵌tomcat-1

前言 我们知道开发spring boot项目&#xff0c;在启动类上添加注解SpringBootApplication &#xff0c;然后引入要自动注入的组件依赖&#xff0c;然后现application.properties中加上相应配置就可以自动注入这个组件&#xff0c;那么下面看看自动注入组件是如何实现的 一、S…

Idea 结合docker-compose 发布项目

Idea 结合docker-compose 发布项目 这里写目录标题 Idea 结合docker-compose 发布项目Docker 开启远程访问功能 添加相应端口配置IDEA 链接Docker配置项目 docker-compose.yml本地还需要安装 dockerwin11 安装本地Docker 可能存在问题 Linux内核不是最新 Docker 开启远程访问功…

回文链表——力扣234

文章目录 题目描述法一 将值复制到数组中后用双指针法法二 快慢指针 题目描述 法一 将值复制到数组中后用双指针法 class Solution { public:bool isPalindrome(ListNode* head) {vector<int> v;while(head!NULL){v.emplace_back(head->val);head head->next;}for…