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
}
続行