From 0d918fbb695a73e1c95e68d90631f987400a58d1 Mon Sep 17 00:00:00 2001 From: zicla Date: Thu, 29 Nov 2018 17:34:53 +0800 Subject: [PATCH] Try to abstract the context entity. --- main.go | 7 ++++--- rest/context.go | 39 ++++++++++++++++++++++++--------------- rest/router.go | 16 +++++++++++++--- rest/user_controller.go | 1 - rest/user_service.go | 29 +++++++++++++++++++++++++++++ rest/util_cache.go | 40 ++++++++++------------------------------ 6 files changed, 80 insertions(+), 52 deletions(-) create mode 100644 rest/user_service.go diff --git a/main.go b/main.go index c3b8cf3..3c4ff7b 100644 --- a/main.go +++ b/main.go @@ -12,10 +12,11 @@ func main() { //将运行时参数装填到config中去。 rest.PrepareConfigs() - context := rest.NewContext() - defer context.Destroy() - http.Handle("/", context.Router) + rest.CONTEXT.Init() + defer rest.CONTEXT.Destroy() + + http.Handle("/", rest.CONTEXT.Router) dotPort := fmt.Sprintf(":%v", rest.CONFIG.ServerPort) diff --git a/rest/context.go b/rest/context.go index 8f34521..fb08fa5 100644 --- a/rest/context.go +++ b/rest/context.go @@ -6,16 +6,23 @@ import ( "reflect" ) +//全局唯一的上下文(在main函数中初始化) +var CONTEXT = &Context{} + //上下文,管理数据库连接,管理所有路由请求,管理所有的单例component. type Context struct { //数据库连接 DB *gorm.DB - //处理所有路由请求 - Router *Router + //session缓存 + SessionCache *CacheTable + //TODO:日志相关内容 + //各类的Bean Map。这里面是包含ControllerMap中所有元素 BeanMap map[string]IBean //只包含了Controller的map ControllerMap map[string]IController + //处理所有路由请求 + Router *Router } func (this *Context) OpenDb() { @@ -33,33 +40,34 @@ func (this *Context) OpenDb() { func (this *Context) CloseDb() { if this.DB != nil { - this.DB.Close() + err := this.DB.Close() + if err != nil { + fmt.Println("关闭数据库连接出错", err) + } } } //构造方法 -func NewContext() *Context { - - context := &Context{} +func (this *Context) Init() { //处理数据库连接的开关。 - context.OpenDb() + this.OpenDb() + + //创建一个用于存储session的缓存。 + this.SessionCache = NewCacheTable() //初始化Map - context.BeanMap = make(map[string]IBean) - context.ControllerMap = make(map[string]IController) + this.BeanMap = make(map[string]IBean) + this.ControllerMap = make(map[string]IController) //注册各类Beans.在这个方法里面顺便把Controller装入ControllerMap中去。 - context.registerBeans() + this.registerBeans() //初始化每个bean. - context.initBeans() + this.initBeans() //初始化Router. 这个方法要在Bean注册好了之后才能。 - context.Router = NewRouter(context) - - return context - + this.Router = NewRouter(this) } //注册一个Bean @@ -129,6 +137,7 @@ func (this *Context) registerBeans() { //user this.registerBean(new(UserController)) this.registerBean(new(UserDao)) + this.registerBean(new(UserService)) } diff --git a/rest/router.go b/rest/router.go index cbe0025..8b9b878 100644 --- a/rest/router.go +++ b/rest/router.go @@ -12,8 +12,9 @@ import ( //用于处理所有前来的请求 type Router struct { - context *Context - routeMap map[string]func(writer http.ResponseWriter, request *http.Request) + context *Context + userService *UserService + routeMap map[string]func(writer http.ResponseWriter, request *http.Request) } //构造方法 @@ -23,6 +24,14 @@ func NewRouter(context *Context) *Router { routeMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)), } + + //装载userService. + b := context.GetBean(router.userService) + if b, ok := b.(*UserService); ok { + router.userService = b + } + + //将Controller中的路由规则装载机进来 for _, controller := range context.ControllerMap { routes := controller.RegisterRoutes() for k, v := range routes { @@ -139,6 +148,8 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) path := request.URL.Path if strings.HasPrefix(path, "/api") { + //统一处理用户的身份信息。 + this.userService.enter(writer, request) if handler, ok := this.routeMap[path]; ok { @@ -198,5 +209,4 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) } - } diff --git a/rest/user_controller.go b/rest/user_controller.go index 04fb2ab..1d1f933 100644 --- a/rest/user_controller.go +++ b/rest/user_controller.go @@ -67,7 +67,6 @@ func (this *UserController) Login(writer http.ResponseWriter, request *http.Requ expiration = expiration.AddDate(0, 0, 7) //持久化用户的session. - session := &Session{ UserUuid: user.Uuid, Ip: GetIpAddress(request), diff --git a/rest/user_service.go b/rest/user_service.go new file mode 100644 index 0000000..d182d2a --- /dev/null +++ b/rest/user_service.go @@ -0,0 +1,29 @@ +package rest + +import ( + "net/http" +) + +//@Service +type UserService struct { + Bean + userDao *UserDao +} + +//初始化方法 +func (this *UserService) Init(context *Context) { + + //手动装填本实例的Bean. 这里必须要用中间变量方可。 + b := context.GetBean(this.userDao) + if b, ok := b.(*UserDao); ok { + this.userDao = b + } + +} + +//装载session信息,如果session没有了根据cookie去装填用户信息。 +//在所有的路由最初会调用这个方法 +func (this *UserService) enter(writer http.ResponseWriter, request *http.Request) { + + +} diff --git a/rest/util_cache.go b/rest/util_cache.go index dcf6e58..0ecc617 100644 --- a/rest/util_cache.go +++ b/rest/util_cache.go @@ -96,8 +96,6 @@ func (item *CacheItem) SetDeleteCallback(f func(interface{})) { type CacheTable struct { sync.RWMutex - //缓存表名 - name string //所有缓存项 items map[interface{}]*CacheItem // 触发缓存清理的定时器 @@ -166,9 +164,9 @@ func (table *CacheTable) checkExpire() { table.cleanupTimer.Stop() } if table.cleanupInterval > 0 { - table.log("Expiration check triggered after", table.cleanupInterval, "for table", table.name) + table.log("Expiration check triggered after", table.cleanupInterval, "for table") } else { - table.log("Expiration check installed for table", table.name) + table.log("Expiration check installed for table") } // 为了不抢占锁,采用临时的items. @@ -220,7 +218,7 @@ func (table *CacheTable) Add(key interface{}, duration time.Duration, data inter // 将缓存项放入表中 table.Lock() - table.log("Adding item with key", key, "and lifespan of", duration, "to table", table.name) + table.log("Adding item with key", key, "and lifespan of", duration, "to table") table.items[key] = item // 取出需要的东西,释放锁 @@ -267,7 +265,7 @@ func (table *CacheTable) Delete(key interface{}) (*CacheItem, error) { table.Lock() defer table.Unlock() - table.log("Deleting item with key", key, "created on", r.createTime, "and hit", r.count, "times from table", table.name) + table.log("Deleting item with key", key, "created on", r.createTime, "and hit", r.count, "times from table") delete(table.items, key) return r, nil @@ -292,7 +290,7 @@ func (table *CacheTable) NotFoundAdd(key interface{}, lifeSpan time.Duration, da } item := NewCacheItem(key, lifeSpan, data) - table.log("Adding item with key", key, "and lifespan of", lifeSpan, "to table", table.name) + table.log("Adding item with key", key, "and lifespan of", lifeSpan, "to table") table.items[key] = item // 取出需要的内容,释放锁 @@ -344,7 +342,7 @@ func (table *CacheTable) Flush() { table.Lock() defer table.Unlock() - table.log("Flushing table", table.name) + table.log("Flushing table") table.items = make(map[interface{}]*CacheItem) table.cleanupInterval = 0 @@ -405,27 +403,9 @@ func (table *CacheTable) log(v ...interface{}) { table.logger.Println(v...) } -var ( - cacheTableMap = make(map[string]*CacheTable) - cacheTableMutex sync.RWMutex -) - -//统一管理所有的缓存表,如果没有就返回一个新的。 -func Cache(table string) *CacheTable { - cacheTableMutex.RLock() - t, ok := cacheTableMap[table] - cacheTableMutex.RUnlock() - - if !ok { - t = &CacheTable{ - name: table, - items: make(map[interface{}]*CacheItem), - } - - cacheTableMutex.Lock() - cacheTableMap[table] = t - cacheTableMutex.Unlock() +//新建一个缓存Table +func NewCacheTable() *CacheTable { + return &CacheTable{ + items: make(map[interface{}]*CacheItem), } - - return t }