Go-Spring 入门篇(六)

序言

示例代码 github.com/acrossmountain/gs-demo

上章 Go-Spring 入门篇(五) 讲到对上传服务的抽象,完成了 controlerservice 的解耦。

本章我们实现一个对象存储和本地文件存储能力的更换,通过 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 的管理界面,可以发现文件已经上传成功。

Go-Spring 入门篇(六)

修改 config/application.propertiesminio.enable 可以切换存储能力。

到此我们的入门篇就结束了。

谢谢大家,嘻嘻!

官网及交流

Go-Spring 官网
Github

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!