Try to abstract the context entity.

This commit is contained in:
zicla
2018-11-29 17:34:53 +08:00
parent fcdcf6da60
commit 0d918fbb69
6 changed files with 80 additions and 52 deletions

View File

@ -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))
}

View File

@ -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)
}
}

View File

@ -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),

29
rest/user_service.go Normal file
View File

@ -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) {
}

View File

@ -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
}