beego使用及びソース分析一(controler登録ルートコントローラとhttp serverサーバー実現)



本文は最も簡単な使い方で、beegoのソースコードを読み、beegoの底辺実現の細部を探ってみます。廬山の本当の姿を見てみます。
二つの部分の基礎が必要です。一つはgolangのnet/http serverの基礎です。二つは反射reflectの基礎です。
net/http serverの基礎はbeegoの下のhttpサーバーの実現を理解するために用いられます。
reflectベースは、beego登録コントローラとurlマッピング起動方法を知るために使用されています。beegoの下の階はどうやって呼び出しますか?
一:ベエゴの使用例
router.goファイル
package routers

import (
	"my_beego_project/controllers"
	"github.com/astaxie/beego"
)

func init() {
    beego.Router("/", &controllers.MainController{},"POST:PostTest")
}
controller.goファイル
package controllers

import (
	"github.com/astaxie/beego"
)

type MainController struct {
	beego.Controller
}

func (c *MainController) PostTest() {
	c.Data["Website"] = "beego.me"
	c.Data["Email"] = "[email protected]"
	c.ServeJSON()
}

メールファイル
package main

import (
	_ "my_beego_project/routers"
	"github.com/astaxie/beego"
)

func main() {
	beego.Run()
}
スーパーシンプルで、余分なコードがありません。
ソース分析一:beegoのhttp server
1.まずmain.goのbeego.Run()を見ます。
func Run(params ...string) {

	initBeforeHTTPRun()

	if len(params) > 0 && params[0] != "" {
		strs := strings.Split(params[0], ":")
		if len(strs) > 0 && strs[0] != "" {
			BConfig.Listen.HTTPAddr = strs[0]
		}
		if len(strs) > 1 && strs[1] != "" {
			BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
		}

		BConfig.Listen.Domains = params
	}

	BeeApp.Run()
}
この関数も簡単で、着信した可変パラメータparamsを解析し、グローバル構成の傍受のアドレスとポートとドメイン名に解析することができます。
その後BeeApp.Run()を実行して、私達はBeeApp.Run()を引き続き見て、ここのBeeAppは対象で、Runは対象の方法で、しばらく私達は先に見ないで、方法を引き続き見ます。
2.BeeApp.Run()
func (app *App) Run(mws ...MiddleWare) {
    ...
    app.Server.Handler = app.Handlers

    ...
    if BConfig.Listen.EnableHTTP {
		go func() {
			app.Server.Addr = addr
			logs.Info("http server Running on http://%s", app.Server.Addr)
			if BConfig.Listen.ListenTCP4 {
				...
			} else {
				if err := app.Server.ListenAndServe(); err != nil {
					logs.Critical("ListenAndServe: ", err)
					time.Sleep(100 * time.Microsecond)
					endRunning 
他は本章のメインラインのコードではありません。私はすでに注釈を落としました。
http serverはbeegoでカスタマイズされたserverであり、ap.Server.ListenAndServe()を使ってサービスを開始し、Serverのために傍受アドレスを設定していることが主に観測されます。
そして、カスタマイズしたHandler、このHandlerはBeeApp構造体そのものですが、このHandlerは何ですか?このBeeApp構造体は何ですか?コードを見続けます。
3.BeeApp構造
func init() {
	// create beego application
	BeeApp = NewApp()
}

// App defines beego application with a new PatternServeMux.
type App struct {
	Handlers *ControllerRegister
	Server   *http.Server
}

// NewApp returns a new beego application.
func NewApp() *App {
	cr := NewControllerRegister()
	app := &App{Handlers: cr, Server: &http.Server{}}
	return app
}
はい、BeeAppはApp構造体のオブジェクトです。この構造体はメンバーが二人います。BeeAppはグローバルオブジェクトです。NewAppを通じて直接コード初期化時に割り当てられました。
この対象のServerは初期化時に直接に割り当てられた空き構造体です。中のパラメータは後から順に記入するべきです。しかし、これは本章の重点ではなく、
主にこのコントローラのHandlersを見てください。http serverのHandlerは全部ネット/httpの下のHandlerインターフェースを継承しています。このインターフェースはServeHTTP方法があります。この方法こそhttp serverの核心です。
このBeegoのHandlerを見て、この構造のServeHTTP法は何をしているかを確認します。
3.NewController Register
type ControllerRegister struct {
	routers      map[string]*Tree
	enablePolicy bool
	policies     map[string]*Tree
	enableFilter bool
	filters      [FinishRouter + 1][]*FilterRouter
	pool         sync.Pool
}

// NewControllerRegister returns a new ControllerRegister.
func NewControllerRegister() *ControllerRegister {
	return &ControllerRegister{
		routers:  make(map[string]*Tree),
		policies: make(map[string]*Tree),
		pool: sync.Pool{
			New: func() interface{} {
				return beecontext.NewContext()
			},
		},
	}
}
この関数は主にController Registerオブジェクトを構築しています。このオブジェクトはいくつかのメンバーがいますが、すべて公開されていません。その中にroutersがあります。
beegoサーバーはurlによって具体的な方法にマッピングする機能に関連しています。
でも、今はController Register構造のServeHTTPの方法を見てみます。http要求を具体的にどう処理しますか?どこでやりましたか?
コードを見る:
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {

    ...
    routerInfo, findRouter = p.FindRouter(context)
    ...
    if routerInfo.routerType == routerTypeRESTFul {
        ...
    }else if routerInfo.routerType == routerTypeHandler {
        ...
    }else {
        runMethod = method
    }

    ...
    vc := reflect.ValueOf(execController)
	method := vc.MethodByName(runMethod)
	in := param.ConvertParams(methodParams, method.Type(), context)
	out := method.Call(in)
    ...

}
同様に、無関係コードが省略されていますが、Controller RegisterはカスタムHandlerとして、http要求はすべてServeHTTP方法を経て、中でルートを行い、対応する方法を呼び出して論理処理を行います。
ここでは反射によって具体的な方法に呼び出される。ここには意外にもパラメーターが入っています。パラメーターは何ですか?私のソース追跡の結果、Nilです。つまりパラメータが存在しないということはおかしいです。
 
ソース分析2:controller登録ルート
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
	BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
	return BeeApp
}
続行