boot.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package boot
  2. import (
  3. "context"
  4. "github.com/dgrijalva/jwt-go"
  5. redisLib "github.com/go-redis/redis/v8"
  6. "github.com/gogf/gf/frame/g"
  7. "github.com/gogf/gf/net/ghttp"
  8. "go.uber.org/dig"
  9. "gorm.io/gorm"
  10. "gxt-api-frame/app/bll/impl"
  11. "gxt-api-frame/app/errors"
  12. "gxt-api-frame/library/auth"
  13. "gxt-api-frame/library/gplus"
  14. "gxt-api-frame/library/logger"
  15. "gxt-api-frame/library/middleware"
  16. "gxt-api-frame/library/redis"
  17. "gxt-api-frame/library/utils"
  18. "gxt-api-frame/router"
  19. "os"
  20. )
  21. // VERSION 定义应用版本号
  22. const VERSION = "1.0.0"
  23. func init() {
  24. // 初始化logger
  25. logger.Init(g.Cfg().GetString("common.run_mode"))
  26. logger.SetVersion(VERSION)
  27. logger.SetTraceIdFunc(utils.NewTraceID)
  28. ctx := logger.NewTraceIDContext(context.Background(), utils.NewTraceID())
  29. Init(ctx)
  30. }
  31. // 初始化App,
  32. // TODO: 返回释放回调,暂时没调用
  33. func Init(ctx context.Context) func() {
  34. logger.Printf(ctx, "服务启动,运行模式:%s,版本号:%s,进程号:%d", g.Cfg().Get("common.run_mode"), VERSION, os.Getpid())
  35. // 初始化依赖注入容器
  36. container, call := buildContainer(ctx)
  37. // 初始化路由注册
  38. s := g.Server()
  39. // 每个请求生成新的追踪Id,如果上下文件中没有trace-id
  40. s.Use(middleware.TraceIdMiddleware())
  41. // 统一处理内部错误
  42. s.Use(func(r *ghttp.Request) {
  43. r.Middleware.Next()
  44. if err := r.GetError(); err != nil {
  45. gplus.ResError(r, err)
  46. }
  47. })
  48. _ = initJwtAuth(ctx, container)
  49. router.InitRouters(s, container)
  50. return func() {
  51. if call != nil {
  52. call()
  53. }
  54. }
  55. }
  56. // 初始化jwt认证,可以把相关配置放到config.toml中
  57. func initJwtAuth(ctx context.Context, container *dig.Container) error {
  58. var opts []auth.Option
  59. opts = append(opts, auth.SetExpired(g.Cfg().GetInt("jwt.expired")))
  60. opts = append(opts, auth.SetSigningKey([]byte(g.Cfg().GetString("jwt.signing_key"))))
  61. opts = append(opts, auth.SetKeyfunc(func(t *jwt.Token) (interface{}, error) {
  62. if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
  63. return nil, errors.ErrInvalidToken
  64. }
  65. return []byte(g.Cfg().GetString("jwt.signing_key")), nil
  66. }))
  67. switch g.Cfg().GetString("jwt.signing_method") {
  68. case "HS256":
  69. opts = append(opts, auth.SetSigningMethod(jwt.SigningMethodHS256))
  70. case "HS384":
  71. opts = append(opts, auth.SetSigningMethod(jwt.SigningMethodHS384))
  72. case "HS512":
  73. opts = append(opts, auth.SetSigningMethod(jwt.SigningMethodHS512))
  74. }
  75. return container.Provide(func() auth.Auther { return auth.New(opts...)})
  76. }
  77. // 初始化redis
  78. func initRedis(ctx context.Context, container *dig.Container) func() {
  79. addr := g.Cfg().GetString("redis.addr")
  80. password := g.Cfg().GetString("redis.password")
  81. db := g.Cfg().GetInt("redis.db")
  82. redisCli := redis.Init(ctx, addr, password, db)
  83. logger.Printf(ctx, "REDIS初始化成功,当前服务器[%s]", addr)
  84. // 注入redis client
  85. _ = container.Provide(func() *redisLib.Client {
  86. return redisCli
  87. })
  88. return func() {
  89. _ = redisCli.Close()
  90. }
  91. }
  92. // 初始化存储,目前只初始化gorm
  93. func initStore(ctx context.Context, container *dig.Container) (func(), error) {
  94. var storeCall func()
  95. db, err := initGorm()
  96. if err != nil {
  97. return storeCall, err
  98. }
  99. // 如果自动映射数据表
  100. if g.Cfg().GetBool("gorm.enable_auto_migrate") {
  101. err = autoMigrate(db)
  102. if err != nil {
  103. return storeCall, err
  104. }
  105. }
  106. // 注入DB
  107. _ = container.Provide(func() *gorm.DB { return db })
  108. // 注入model接口
  109. _ = InjectModel(container)
  110. storeCall = func() {
  111. sqlDb, _ := db.DB()
  112. _ = sqlDb.Close()
  113. }
  114. logger.Printf(ctx, "MYSQL初始化成功, 服务器[%s], 数据库[%s]",
  115. g.Cfg().GetString("mysql.host"),
  116. g.Cfg().GetString("mysql.db_name"))
  117. return storeCall, nil
  118. }
  119. // 构建依赖注入容器
  120. func buildContainer(ctx context.Context) (*dig.Container, func()) {
  121. container := dig.New()
  122. // 初始化存储模块
  123. storeCall, err := initStore(ctx, container)
  124. if err != nil {
  125. panic(err)
  126. }
  127. // 初始化redis模块
  128. var redisCall func()
  129. if g.Cfg().GetBool("redis.enable") {
  130. redisCall = initRedis(ctx, container)
  131. }
  132. // 注入bll
  133. impl.Inject(container)
  134. return container, func() {
  135. if storeCall != nil {
  136. storeCall()
  137. }
  138. if redisCall != nil {
  139. redisCall()
  140. }
  141. }
  142. }