2019-08-22, beego代码走读,三、Controller & Template

// Implement http.Handler interface.
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)

中使用反射库调用了controller

        //Invoke the request handler
        var execController ControllerInterface
        if routerInfo != nil && routerInfo.initialize != nil {
            execController = routerInfo.initialize()
        } else {
            vc := reflect.New(runRouter)
            var ok bool
            execController, ok = vc.Interface().(ControllerInterface)
            if !ok {
                panic("controller is not ControllerInterface")
            }
        }

        //call the controller init function
        execController.Init(context, runRouter.Name(), runMethod, execController)

        //call prepare function
        execController.Prepare()

并调用ControllerInterfaceRender方法。

            //render template
            if !context.ResponseWriter.Started && context.Output.Status == 0 {
                if BConfig.WebConfig.AutoRender {
                    if err := execController.Render(); err != nil {
                        logs.Error(err)
                    }
                }
            }

用到一个bytes.Buffer作为内存的缓存,看封装挺简单的。

func (c *Controller) renderTemplate() (bytes.Buffer, error) {
    var buf bytes.Buffer
    //略...
}
bytes.Buffer方法

调用的ExecuteViewPathTemplate方法是线程安全的,A template will be executed safely in parallel.

// ExecuteViewPathTemplate applies the template with name and from specific viewPath to the specified data object,
// writing the output to wr.
// A template will be executed safely in parallel.
func ExecuteViewPathTemplate(wr io.Writer, name string, viewPath string, data interface{}) error {
    if BConfig.RunMode == DEV {
        templatesLock.RLock()
        defer templatesLock.RUnlock()
    }
    //略...
}

看一下是如何达到安全的,使用到了templatesLock,读写锁sync.RWMutex

    templatesLock        sync.RWMutex

看一下RWMutex的设计,RWMutex包含了一把Mutex锁和四个int32值,其中Mutex锁用于写锁定,而读锁用的是atomic实现的。

type RWMutex struct {
    w           Mutex  // held if there are pending writers
    writerSem   uint32 // semaphore for writers to wait for completing readers
    readerSem   uint32 // semaphore for readers to wait for completing writers
    readerCount int32  // number of pending readers
    readerWait  int32  // number of departing readers
}

你可能感兴趣的:(2019-08-22, beego代码走读,三、Controller & Template)