Spring 中的资源加载:ClassPathResource 与 ResourceLoader 的正确使用方式
·
文章目录
在 Spring 项目中,加载资源时你一定见过这两种写法:
new ClassPathResource("config/app.yml");
resourceLoader.getResource("classpath:config/app.yml");
它们都能加载 classpath 下的资源,但到底有什么区别?应该用哪个?
一、先给结论
能用
ResourceLoader的地方,优先用ResourceLoader;
只有在“明确只加载 classpath”时,才用ClassPathResource。
二、两者是什么关系?
1️⃣ 共同点
- 两者最终返回的都是
Resource - 都属于 Spring 的 资源抽象体系
- 都支持
InputStream方式读取
InputStream is = resource.getInputStream();
2️⃣ 本质区别(一句话)
| 维度 | ClassPathResource | ResourceLoader |
|---|---|---|
| 类型 | 具体实现类 | 统一加载入口(接口) |
| 职责 | 只负责 classpath | 负责“选择合适的 Resource” |
| 扩展性 | 低 | 高 |
👉 ClassPathResource 是“点对点”
👉 ResourceLoader 是“调度中心”
三、ClassPathResource:直接、明确、但不通用
1️⃣ 使用方式
ClassPathResource resource =
new ClassPathResource("config/app.yml");
📌 只能加载:
classpath:/config/app.yml
2️⃣ 适用场景
| 场景 | 是否适合 |
|---|---|
| jar 内资源 | ✅ |
| 固定资源路径 | ✅ |
| 只允许 classpath | ✅ |
| 可配置路径 | ❌ |
| 外部文件 | ❌ |
3️⃣ 局限性(必须知道)
❌ 不能加载:
file:/data/app.yml
http://xxx/app.yml
❌ 构造器 不能写 classpath: 前缀
四、ResourceLoader:Spring 推荐的“统一入口”
1️⃣ 使用方式
@Autowired
private ResourceLoader resourceLoader;
Resource resource =
resourceLoader.getResource("classpath:config/app.yml");
2️⃣ 它到底做了什么?
ResourceLoader 会根据前缀 自动选择实现类:
| 前缀 | 实际返回 |
|---|---|
| classpath: | ClassPathResource |
| file: | FileSystemResource |
| http(s): | UrlResource |
| 无前缀 | ClassPathResource(默认) |
👉 你不用关心具体实现
五、两者核心对比表(重点)
| 对比点 | ClassPathResource | ResourceLoader |
|---|---|---|
| 角色 | 具体 Resource 实现 | 统一资源入口 |
| 是否推荐 | ⚠️ 场景明确才用 | ✅ 强烈推荐 |
| 支持多协议 | ❌ | ✅ |
| 支持 classpath: | ❌ | ✅ |
| 是否依赖 Spring | 可独立用 | 需要 Spring 容器 |
| 灵活性 | 低 | 高 |
六、典型使用对比(实战)
❌ 写死方式(不推荐)
new ClassPathResource("config/app.yml");
以后如果要支持:
file:/data/app.yml
👉 代码必须重写。
✅ 推荐方式(可扩展)
@Value("${app.config.location}")
private String location;
Resource resource = resourceLoader.getResource(location);
配置可以是:
app:
config:
location: classpath:config/app.yml
或:
app:
config:
location: file:/data/app.yml
👉 代码完全不用动
七、常见误区对照表
| 误区 | 正确理解 |
|---|---|
| ResourceLoader 比 ClassPathResource 慢 | ❌ 几乎无差别 |
| ClassPathResource 更底层更好 | ❌ 只是更具体 |
| jar 中不能读文件 | ❌ 用 Resource |
| ResourceLoader 只能读 classpath | ❌ 支持多协议 |
八、什么时候“必须”用 ClassPathResource?
只有这 2 种情况:
1️⃣ 脱离 Spring 环境(工具类 / main 方法)
2️⃣ 你明确只允许 classpath 资源
九、总结
路径写死 → ClassPathResource
路径可配 → ResourceLoader
ClassPathResource 是实现,
ResourceLoader 是入口。
在 Spring 项目中,优先使用 ResourceLoader,是面向变化的设计。
更多推荐




所有评论(0)