主题
OSS Spring Boot 集成指南
动态数据源(ds 模式)
注解方式切换
java
import cn.com.digitalhainan.oss.source.annatation.Oss;
@Service
public class MultiOssService {
@Autowired
private IObjectStorageService ossService;
@Oss("aliyun-oss")
public ObjectStorageResponse uploadToAliyun(String objectName, byte[] bytes) {
return ossService.upload(objectName, bytes);
}
@Oss("huawei-obs")
public ObjectStorageResponse uploadToHuawei(String objectName, byte[] bytes) {
return ossService.upload(objectName, bytes);
}
}编程式切换
java
import cn.com.digitalhainan.oss.source.OssDynamicDataSourceHolder;
public ObjectStorageResponse uploadWithDataSource(String dataSource, String objectName, byte[] bytes) {
try {
OssDynamicDataSourceHolder.setDataSource(dataSource);
return ossService.upload(objectName, bytes);
} finally {
OssDynamicDataSourceHolder.clearDataSource(); // 必须清除
}
}重要:使用 ds 模式时,务必在 finally 块中调用 OssDynamicDataSourceHolder.clearDataSource()
通用文件服务示例
java
@Service
public class OssFileService {
@Autowired
private IObjectStorageService ossService;
public ObjectStorageResponse upload(MultipartFile file, String directory) throws IOException {
String objectName = directory + "/" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
return ossService.upload(objectName, file.getBytes());
}
public InputStream download(String objectName) {
return ossService.download(objectName);
}
public void delete(String objectName) {
ossService.delete(objectName);
}
public String getTemporaryUrl(String objectName, long expireMinutes) {
long expirationMillis = expireMinutes * 60 * 1000;
return ossService.securityUrlStr(objectName, expirationMillis);
}
}最佳实践
1. 必须优先使用 IObjectStorageService
不要直接使用阿里云/华为云/S3 SDK,统一通过 IObjectStorageService 接口操作。
java
// 正确
@Autowired
private IObjectStorageService ossService;
// 错误 - 不要直接使用底层 SDK
@Autowired
private OSSClient ossClient;2. 数据源切换注意事项
| 方式 | 适用场景 | 注意事项 |
|---|---|---|
注解方式 @Oss | 固定数据源的场景 | 注解在方法或类上 |
| 编程方式 | 动态数据源的场景 | 必须在 finally 中清除 |
3. 文件命名规范
java
// 推荐:使用时间戳+原始文件名,避免重名
String objectName = "uploads/" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
// 或者使用 UUID
String objectName = "files/" + UUID.randomUUID().toString() + "." + getExtension(file.getOriginalFilename());4. 异常处理
java
public ObjectStorageResponse safeUpload(String objectName, byte[] bytes) {
try {
return ossService.upload(objectName, bytes);
} catch (Exception e) {
// 记录日志
log.error("OSS上传失败: objectName={}, error={}", objectName, e.getMessage());
// 根据业务决定是否抛出异常或返回默认值
throw new BusinessException("文件上传失败");
}
}配置模板
开发环境
yaml
digitalhainan:
component:
oss:
client-type: aliyun
endpoint: https://oss-cn-hangzhou.aliyuncs.com
access-key-id: ${OSS_ACCESS_KEY_ID}
access-key-secret: ${OSS_ACCESS_KEY_SECRET}
bucket-name: dev-bucket生产环境(多数据源)
yaml
digitalhainan:
component:
oss:
client-type: ds
default-ds: aliyun-prod
ds:
aliyun-prod:
client-type: aliyun
endpoint: https://oss-cn-hangzhou.aliyuncs.com
access-key-id: ${OSS_ACCESS_KEY_ID}
access-key-secret: ${OSS_ACCESS_KEY_SECRET}
bucket-name: prod-bucket
domain: https://cdn.example.com
aliyun-backup:
client-type: aliyun
endpoint: https://oss-cn-shenzhen.aliyuncs.com
access-key-id: ${OSS_BACKUP_ACCESS_KEY_ID}
access-key-secret: ${OSS_BACKUP_ACCESS_KEY_SECRET}
bucket-name: backup-bucket