Go-Spring 入门篇(六)
序言
上章 Go-Spring 入门篇(五) 讲到对上传服务的抽象,完成了 controler
对 service
的解耦。
本章我们实现一个对象存储和本地文件存储能力的更换,通过 go-spring
提供的 Condition 来限制 Bean 的注册以及动态设置配置项。
Minio
使用 minio 作为远端对象存储服务。
docker-compose
这里我们通过 docker
快速的创建一个本地 minio
服务。
version: "3"
services:
minio:
image: bitnami/minio:latest
ports:
- "9000:9000"
- "9001:9001"
environment:
- MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE
- MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
- BITNAMI_DEBUG=true
config/application.properties
添加 minio
配置。
# minio
minio.enable=true
minio.host=127.0.0.1
minio.port=9000
minio.access=AKIAIOSFODNN7EXAMPLE
minio.secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
minio.secure = false
minio.bucket=gs-demo
modules/minio/minio.go
注册 minio
启动器。
package minio
import (
"context"
"fmt"
"github.com/go-spring/spring-base/log"
"github.com/go-spring/spring-core/gs"
"github.com/go-spring/spring-core/gs/cond"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
type MinioConfig struct {
Enable bool `value:"${minio.enable:=true}"` // 是否启用 HTTP
Host string `value:"${minio.host:=127.0.0.1}"` // HTTP host
Port int `value:"${minio.port:=9000}"` // HTTP 端口
Access string `value:"${minio.access:=}"` // Access
Secret string `value:"${minio.secret:=}"` // Secret
Secure bool `value:"${minio.secure:=true}"` // Secure
Bucket string `value:"${minio.bucket:=}"`
}
func init() {
gs.Provide(clientMinio).
// Bean 名称
Name("minio-client").
// cond.OnProperty 会检查配置项
On(cond.OnProperty("minio.enable", cond.HavingValue("true")))
}
func clientMinio(config MinioConfig) *minio.Client {
// 创建 minio 对象
client, err := minio.New(fmt.Sprintf("%s:%d", config.Host, config.Port), &minio.Options{
Creds: credentials.NewStaticV4(config.Access, config.Secret, ""),
Secure: config.Secure,
})
if err != nil {
panic("minio client error" + err.Error())
}
// 创建存储桶
err = client.MakeBucket(context.Background(), config.Bucket, minio.MakeBucketOptions{
// 嘻嘻,这个桶是外太空的
Region: "waitaikong",
ObjectLocking: false,
})
if err != nil {
panic(fmt.Sprintf("make %s bucket error: %v", config.Bucket, err))
}
log.Infof("%v", client.EndpointURL())
return client
}
记得收集导入到 main.go
services/services.go
本地存储 service
需要在没有注册 minio-client
的情况才注册。
package services
import (
"github.com/minio/minio-go/v7"
"learn/services/filesystem/local"
fminio "learn/services/filesystem/minio"
"learn/types"
"github.com/go-spring/spring-core/gs"
"github.com/go-spring/spring-core/gs/cond"
)
func init() {
gs.Object(new(local.Service)).
Export((*types.FileProvider)(nil)).
// 本地存储,当 minio 不存在时才注册
// 可以添加其它判断条件,例如 aliyun 等
On(cond.Group(cond.And, cond.OnMissingBean((*minio.Client)(nil))))
gs.Object(new(fminio.Service)).
Export((*types.FileProvider)(nil)).
// 当 minio-client 对象存在时
On(cond.OnBean((*minio.Client)(nil)))
}
services/filesystem/minio/minio.go
package minio
import (
// ...
"github.com/minio/minio-go/v7"
)
type Service struct {
// 自动注入 minio-client
Client *minio.Client `autowire:""`
// 存储桶
Bucket string `value:"${minio.bucket}"`
// 存储路径
Dir string `value:"${file.dir}"`
}
func (s *Service) PutObject(name string, r io.Reader, size int64) (string, error) {
// ...
}
func (s *Service) ExistsObject(name string) bool {
// ...
}
然后启动 docker-compose up -d minio
启动 minio
服务。
重新运行 go run main.go
并测试,功能正常。
$ curl -F "file=@./1.jpg" http://127.0.0.1:8080/upload
$ {"code":0,"data":{"url":"temp/1.jpg"},"msg":"上传文件成功"}
$ curl -F "file=@./1.jpg" http://127.0.0.1:8080/upload
$ {"code":-1,"msg":"文件已存在,请勿重复上传"}
上传后,通过 127.0.0.1:9001 在浏览器打开 minio 的管理界面,可以发现文件已经上传成功。
修改 config/application.properties
的 minio.enable
可以切换存储能力。
到此我们的入门篇就结束了。
谢谢大家,嘻嘻!
官网及交流
本作品采用《CC 协议》,转载必须注明作者和本文链接