предисловие
Возможно, фреймворк beego должен стать первым выбором для многих PHP-специалистов, желающих перейти в Китай, потому что beego MVC, ORM и полная документация на китайском языке делают PHP-разработчиков удобными, и я в этом не сомневаюсь. Это похоже на использование ThinkPHP, когда я начал работать с PHP.
Может быть, с улучшением вашего познания вы теперь будете ненавидеть вещи. Например, однажды вы можете постепенно начать ненавидеть beego, вы обнаружите, что на языке гоСумкаРеальный смысл, вы начинаете размышлять о том, действительно ли MVC подходит для go, или вы начинаете чувствовать, что ORM безвкусна в статических языках и так далее. Я просто хочу сказать: "Может быть, ты повзрослел~". Но это не важно, у каждой популярной вещи, естественно, есть место, где мы можем учиться. Сегодняшняя статья очень проста, как заметка, в которой фиксируется мое время на чтение исходного кода beego за последние несколько дней.
Как читать фрейм?
Само собой разумеется, что фреймворк go такой же, как и фреймворк PHP:
- Загрузка конфигурации: Как загрузить файлы конфигурации.
- маршрутизация: проанализируйте, как платформа выполняет соответствующий бизнес через URI.
- ORM: как реализован ORM.
Здесь (1.) и (3.) не что иное, как загрузка файла и реализация парсера sql, я его проигнорирую, и сосредоточусь на реализации роутинга.
Установить
Просто принесите:
// Step1: 安装beego
go get github.com/astaxie/beego
// Step2: 安装bee
go get github.com/beego/bee
// Step3: 用bee工具创建一个新的项目
bee new beego-code-read
анализ кода
go имеет свой собственный http-пакет, и большинство фреймворков go также основаны на этом http-пакете, так что давайте добавим или пересмотрим этот пункт знаний, прежде чем смотреть beego. следующее:
Как запустить http сервер в go
package main
import (
// 导入net/http包
"net/http"
)
func main() {
// ------------------ 使用http包启动一个http服务 方式一 ------------------
// *http.Request http请求内容实例的指针
// http.ResponseWriter 写http响应内容的实例
http.HandleFunc("/v1/demo", func(w http.ResponseWriter, r *http.Request) {
// 写入响应内容
w.Write([]byte("Hello TIGERB !\n"))
})
// 启动一个http服务并监听8888端口 这里第二个参数可以指定handler
http.ListenAndServe(":8888", nil)
}
// 测试我们的服务
// --------------------
// 启动:bee run
// 访问: curl "http://127.0.0.1:8888/v1/demo"
// 响应结果:Hello TIGERB !
ListenAndServe — это дальнейшая инкапсуляция http.Server.В дополнение к описанному выше методу вы также можете использовать http.Server для прямого запуска службы.Для этого требуется установка обработчика, который реализует интерфейс Server.Handler. Когда придет запрос, этот обработчик будет выполненServeHTTP
Методы, как показано ниже:
package main
// 导入net/http包
import (
"net/http"
)
// DemoHandle server handle示例
type DemoHandle struct {
}
// ServeHTTP 匹配到路由后执行的方法
func (DemoHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello TIGERB !\n"))
}
func main() {
// ------------------ 使用http包的Server启动一个http服务 方式二 ------------------
// 初始化一个http.Server
server := &http.Server{}
// 初始化handler并赋值给server.Handler
server.Handler = DemoHandle{}
// 绑定地址
server.Addr = ":8888"
// 启动一个http服务
server.ListenAndServe()
}
// 测试我们的服务
// --------------------
// 启动:bee run
// 访问: curl "http://127.0.0.1:8888/v1/demo"
// 响应结果:Hello TIGERB !
анализ маршрутизации beego
Далее мы начинаем смотреть на код beego. получить доступ"http://127.0.0.1:8080/"
Например, есть три ключевых момента для кода beego, а именно:
-
Старт: main.go ->
beego.Run()
-
Зарегистрировать маршрутизацию: routers\router.go ->
beego.Router("/", &controllers.MainController{})
-
Контроллер: controllers\default.go ->
Get()
Давайте взглянем на подробный анализ 3 ключевых моментов:
Основная работа beego.Run()
// github.com/astaxie/beego/beego.go
func Run(params ...string) {
// 启动http服务之前的一些初始化 忽略 往下看
initBeforeHTTPRun()
// http服务的ip&port设置
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])
}
}
// 又一个run 往下看
BeeApp.Run()
}
// github.com/astaxie/beego/app.go
func (app *App) Run(mws ...MiddleWare) {
// ... 省略
// 看了下这里app.Server的类型就是*http.Server 也就是说用的原生http包 且是上面“go如何启动一个http server”中的第二种方式
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)
// 默认配置false不强制tcp4
if BConfig.Listen.ListenTCP4 {
//...
// 忽略 默认false
} else {
// 关键点 ListenAndServe: app.Server的类型就是*http.Server 所以这里就启动了http服务
if err := app.Server.ListenAndServe(); err != nil {
logs.Critical("ListenAndServe: ", err)
time.Sleep(100 * time.Microsecond)
endRunning <- true
}
}
}()
}
// 阻塞到服务启动
<-endRunning
}
// 看到这里http已经启动了 而且是注册Handler的方式
Затем перейдите к методу ServeHTTP этого обработчика через приведенный выше код.app.Server.Handler = app.Handlers
, мы нашли следующее определение, Handler — этоControllerRegister
Значение , поэтому каждый раз, когда приходит pro-запрос, он будет выполнятьсяControllerRegister.ServeHTTP(rw http.ResponseWriter, r *http.Request)
.
// src/github.com/astaxie/beego/app.go
func init() {
// 调用 创建beego框架实例的方法
BeeApp = NewApp()
}
// App结构体
type App struct {
// 关键的请求回调Handler
Handlers *ControllerRegister
// http包的服务
Server *http.Server
}
func NewApp() *App {
// 初始化http handler
cr := NewControllerRegister()
// 创建beego 实例
app := &App{Handlers: cr, Server: &http.Server{}}
return app
}
Чейз через насbeego.Run()
Код, пока мы получаем вывод:
- Службы начали использовать пакет http
- не использовал
http.HandleFun()
Определение стратегии маршрутизации, но способ регистрации Handler
Итак, Биего прошелbeego.Router()
Управляйте роутингом сами, если придет http запрос, перезвонитеControllerRegister.ServeHTTP(rw http.ResponseWriter, r *http.Request)
метод, вControllerRegister.ServeHTTP(rw http.ResponseWriter, r *http.Request)
метод для сопоставления маршрута и выполнения соответствующего контроллера, который является beegoControllerInterface
Типы методов контроллера, такие как RESTFUL или custom и т. д.
Как beego.Router() регистрирует маршруты
Прежде всего то, как загружается файл маршрутизации, мы нашли вmain.go
Пакет маршрутизации импортируется в файл:
package main
import (
// 导入routers包 只执行init方法
_ "beego-code-read/routers"
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
Выше мы запустили службу http, а затем ключbeego.Router()
Как прописать маршрутизацию. Преследуйте код следующим образом:
beego.Router()
-> BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
-> ControllerRegister.addWithMethodParams(pattern, c, nil, mappingMethods...)
-> ControllerRegister.addToRouter(method, pattern string, r *ControllerInfo)
-> *Tree.AddRouter(pattern string, runObject interface{})
Последний шаг*Tree.AddRouter()
После завершения регистрации роутинга логика кода здесь пока читаться не будет.Пока процесс beego framework выпрямлен.Наконец подытожим весь процесс следующим образом:
Примечание: пакет go import эквивалентен процессу стекирования, сначала импортируйте, а затем выполните init.