当前位置: 首页 > news >正文

[spring6: Resource ResourceLoader ResourceEditor]-加载资源

Resource

Resource 接口为处理和访问不同类型资源(如文件、URL、输入流等)提供了统一的 API,支持资源的存在性检查、读取、转换等操作。

public interface Resource extends InputStreamSource {boolean exists();default boolean isReadable() {return exists();}default boolean isOpen() {return false;}default boolean isFile() {return false;}URL getURL() throws IOException;URI getURI() throws IOException;File getFile() throws IOException;default ReadableByteChannel readableChannel() throws IOException {return Channels.newChannel(getInputStream());}default byte[] getContentAsByteArray() throws IOException {return FileCopyUtils.copyToByteArray(getInputStream());}default String getContentAsString(Charset charset) throws IOException {return FileCopyUtils.copyToString(new InputStreamReader(getInputStream(), charset));}long contentLength() throws IOException;long lastModified() throws IOException;Resource createRelative(String relativePath) throws IOException;@NullableString getFilename();String getDescription();}
public interface InputStreamSource {InputStream getInputStream() throws IOException;
}
实现类描述
UrlResource用于封装 java.net.URL,可以访问任何通过 URL 访问的资源,如文件、HTTPS、FTP 等。
ClassPathResource用于从类路径加载资源,支持使用类加载器或特定类来加载资源。
FileSystemResource基于 java.io.File 的实现,支持文件系统路径,采用 Java NIO API 进行操作。
PathResource基于 java.nio.file.Path 的实现,采用 NIO API,支持文件和 URL 解析,且实现了 WritableResource 接口。
ServletContextResource用于 ServletContext 资源,解析相对路径并在 Web 应用的根目录下查找资源。
InputStreamResource封装已打开的 InputStream,适用于流式访问已打开的资源,避免多次读取。
ByteArrayResource基于给定字节数组的实现,通过 ByteArrayInputStream 来加载内容,适合加载内存中的数据。

ResourceLoader

ResourceLoader 接口用于资源加载策略,通常在 Spring 应用中用于加载文件、类路径或其他类型的资源。它的子接口和实现类则为其功能扩展,支持不同类型的应用上下文或资源解析需求。|

public interface ResourceLoader {/** Pseudo URL prefix for loading from the class path: "classpath:". */String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;Resource getResource(String location);@NullableClassLoader getClassLoader();}

DefaultResourceLoader

DefaultResourceLoader 是 Spring 中用于加载各种类型资源的默认实现,支持通过类路径、文件系统、URL 等方式加载,并允许扩展协议解析器。

// Direct Known Subclasses:
// AbstractApplicationContext, ClassRelativeResourceLoader, FileSystemResourceLoader, ServletContextResourceLoader
public class DefaultResourceLoader implements ResourceLoader {@Nullableprivate ClassLoader classLoader;private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);public DefaultResourceLoader() {}public DefaultResourceLoader(@Nullable ClassLoader classLoader) {this.classLoader = classLoader;}public void addProtocolResolver(ProtocolResolver resolver) {Assert.notNull(resolver, "ProtocolResolver must not be null");this.protocolResolvers.add(resolver);}@SuppressWarnings("unchecked")public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());}public void clearResourceCaches() {this.resourceCaches.clear();}@Overridepublic Resource getResource(String location) {Assert.notNull(location, "Location must not be null");for (ProtocolResolver protocolResolver : getProtocolResolvers()) {Resource resource = protocolResolver.resolve(location, this);if (resource != null) {return resource;}}if (location.startsWith("/")) {return getResourceByPath(location);}else if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try {// Try to parse the location as a URL...URL url = ResourceUtils.toURL(location);return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));}catch (MalformedURLException ex) {// No URL -> resolve as resource path.return getResourceByPath(location);}}}protected Resource getResourceByPath(String path) {return new ClassPathContextResource(path, getClassLoader());}protected static class ClassPathContextResource extends ClassPathResource implements ContextResource {public ClassPathContextResource(String path, @Nullable ClassLoader classLoader) {super(path, classLoader);}@Overridepublic String getPathWithinContext() {return getPath();}@Overridepublic Resource createRelative(String relativePath) {String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath);return new ClassPathContextResource(pathToUse, getClassLoader());}}
}

ResourcePatternResolver

ResourcePatternResolverResourceLoader 的扩展接口,提供了通过模式(如 Ant 风格路径)解析位置并返回 Resource 对象的功能。它支持 classpath*: 前缀来获取类路径和模块路径中所有匹配的资源。

// "classpath:META-INF/config.xml" 只匹配 第一个 META-INF/config.xml
// "classpath*:META-INF/config.xml" 匹配 所有 JAR 包 和 所有 META-INF 目录 下的 config.xml// PathMatchingResourcePatternResolver
public interface ResourcePatternResolver extends ResourceLoader {String CLASSPATH_ALL_URL_PREFIX = "classpath*:";Resource[] getResources(String locationPattern) throws IOException;}

ResourceLoaderAware

ResourceLoaderAware 接口允许对象在 Spring 容器中获取并使用 ResourceLoader 来加载资源。

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

ResourceEditor

ResourceEditor 通过继承 PropertyEditorSupport 提供了对资源路径的自动解析和加载功能。它能够将字符串路径转换为 Resource 类型,同时支持占位符解析和动态路径处理。这使得资源的配置和加载变得更加灵活与便捷,尤其适用于需要根据配置或环境动态加载资源的场景。

public class ResourceEditor extends PropertyEditorSupport {private final ResourceLoader resourceLoader;@Nullableprivate PropertyResolver propertyResolver;private final boolean ignoreUnresolvablePlaceholders;public ResourceEditor() {this(new DefaultResourceLoader(), null);}public ResourceEditor(ResourceLoader resourceLoader, @Nullable PropertyResolver propertyResolver) {this(resourceLoader, propertyResolver, true);}public ResourceEditor(ResourceLoader resourceLoader, @Nullable PropertyResolver propertyResolver,boolean ignoreUnresolvablePlaceholders) {Assert.notNull(resourceLoader, "ResourceLoader must not be null");this.resourceLoader = resourceLoader;this.propertyResolver = propertyResolver;this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;}@Overridepublic void setAsText(String text) {if (StringUtils.hasText(text)) {String locationToUse = resolvePath(text).trim();setValue(this.resourceLoader.getResource(locationToUse));}else {setValue(null);}}protected String resolvePath(String path) {if (this.propertyResolver == null) {this.propertyResolver = new StandardEnvironment();}return (this.ignoreUnresolvablePlaceholders ? this.propertyResolver.resolvePlaceholders(path) :this.propertyResolver.resolveRequiredPlaceholders(path));}@Override@Nullablepublic String getAsText() {Resource value = (Resource) getValue();try {return (value != null ? value.getURL().toExternalForm() : "");}catch (IOException ex) {return null;}}}
http://www.dtcms.com/a/279486.html

相关文章:

  • RocketMQ消息模型
  • 选择一个系统作为主数据源的优势与考量
  • Java-ThreadLocal
  • 微信131~140
  • Linux连接跟踪Conntrack:原理、应用与内核实现
  • OSPF高级特性之GR
  • echarts应用到swiper 轮播图中,每次鼠标一点击图表所在slide,图表就会消失
  • LSV负载均衡
  • PostgreSQL ExecInitIndexScan 函数解析
  • k8s-高级调度(二)
  • 如何使用Cisco DevNet提供的免费ACI学习实验室(Learning Labs)?(Grok3 回答)
  • PostgreSQL 16 Administration Cookbook 读书笔记:第6章 Security
  • DLL 文件 OSError: [WinError 1401] 应用程序无法启动问题解决
  • 七、深度学习——RNN
  • HTTPS 协议原理
  • ZYNQ双核通信终极指南:FreeRTOS移植+OpenAMP双核通信+固化实战
  • 一文明白AI、AIGC、LLM、GPT、Agent、workFlow、MCP、RAG概念与关系
  • 浏览器防录屏是怎样提高视频安全性?
  • 现有医疗AI记忆、规划与工具使用的创新路径分析
  • 【Linux网络】多路转接poll、epoll
  • vue3 JavaScript 获取 el-table 单元格 赋红色外框
  • mac上用datagrip连接es
  • MFC/C++语言怎么比较CString类型最后一个字符
  • K8S的平台核心架构思想[面向抽象编程]
  • LVS(Linux Virtual Server)集群技术详解
  • linux 内核: 访问当前进程的 task_struct
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 架构搭建
  • C++-linux 6.makefile和cmake
  • 深入掌握Performance面板与LCP/FCP指标优化指南
  • 学习笔记——农作物遥感识别与大范围农作物类别制图的若干关键问题