GridFsTemplate必须显式传入bucket名(如"files")才能生效,否则因Spring Boot未自动配置而报NoSuchBeanDefinitionException;默认使用fs桶,多桶需通过@Bean声明不同名称并注入对应bucket参数。

直接用 GridFsTemplate 就能上传文件,但必须配对指定 bucket 名,否则默认写进 fs,且无法覆盖;不显式声明 bucket 时,GridFsTemplate 和 GridFSBucket 的行为不一致,容易误删或查不到文件。
GridFsTemplate 构造时必须传 bucket 名才能隔离存储
Spring Boot 自动配置的 GridFsTemplate 默认只绑定 fs bucket。如果要区分「临时文件」和「正式文件」,不能靠改配置项,得手动定义多个 bean,并在构造时传入 bucket 名:
-
GridFsTemplate的构造函数支持第三个参数String bucket,例如new GridFsTemplate(dbFactory, converter, "tempFs") - 不传该参数时,底层仍用
fs,哪怕你在application.properties里写了spring.data.mongodb.grid-fs-database也没用 - 每个自定义 bean 必须用
@Bean(name="xxx")显式命名,否则@Autowired会因类型冲突报错
application.properties 中的配置对 GridFsTemplate 无效
很多人以为加了下面这行就能切换 bucket:
spring.data.mongodb.grid-fs-database=custom_db
其实它只影响 GridFSBucket 的数据库选择,对 GridFsTemplate 完全无感。真正起作用的是构造时传入的 bucket 字符串 —— 它会决定操作哪一组 .files 和 .chunks 集合(如 tempFs.files 和 tempFs.chunks)。
- bucket 名就是集合前缀,MongoDB 内部按
{bucket}.files/{bucket}.chunks拆分数据 - 如果你配了
spring.data.mongodb.database=test,又用"tempFs"构造模板,实际操作的是test.tempFs.files - 不要试图用
@Primary替换默认 bean,会导致GridFSBucket注入失败
store() 方法的 contentType 和 metadata 处理有隐式规则
GridFsTemplate.store(InputStream, String, String, Document) 第三个参数是 contentType,不是文件后缀,也不是可选字段:
- 若传
null或空字符串,MongoDB 会写入contentType: null,后续用findByContentType()查不到 -
metadata中的字段名不能含点(.)或美元符($),否则插入失败并抛IllegalArgumentException - 推荐统一用
Document.parse("{\"type\":\"image\",\"userId\":\"123\"}")构建 metadata,避免BasicDBObject在新版本中被弃用 - 文件名(第二个参数)会被存入
filename字段,但 MongoDB 不校验唯一性,同名文件会共存,靠_id区分
真正容易被忽略的是:同一个 bucket 下,GridFsTemplate.delete(Query) 会批量删掉所有匹配的 .files 记录,但对应 .chunks 不会自动清理 —— 必须靠 MongoDB 后台的 TTL 索引或手动跑 db.tempFs.chunks.remove(...),否则磁盘空间只增不减。











