简介
Martini(https://github.com/go-martini/martini)是一个Golang编写的web框架,很轻巧,其核心代码加起来也就1000行左右,能迅速上手。
基础
Martini的核心是inject(https://github.com/codegangsta/inject),采用Golang反射特性实现依赖注入,其介绍参见http://my.oschina.net/goal/blog/195036
关于代码风格
martini里代码通常是这样的:先定义一个interface,随后定义一个实现的struct,后面就是相关方法的实现了,然后再定义一个struct。这样看起来比较清爽,但是不喜欢定义结构和方法的顺序,因为在编写一个方法时,通常需要引用同一个源代码文件中的另一个结构及其方法,导致看代码时候需要经常在同一个源代码文件里上下跳转,显得不大方便。
martini.go
此源文件是martini两个核心文件之一(另一个是router.go),从中可以看到程序运行的主流程,了解框架的概貌。
一 数据结构
type Martini struct {
inject.Injector
handlers []Handler
action Handler
logger *log.Logger
}
type ClassicMartini struct {
*Martini
Router
}
type Context struct {
inject.Injector
Next()
Written() bool
}
type context struct {
inject.Injector
handlers []Handler
action Handler
rw ResponseWriter
index int
}
Martini是框架核心的struct,包含了相关的处理器(Handler),可以通过依赖注入的方式添加处理器,非常灵活。
Martini不包含有路由处理功能,故需要开发者自己添加路由处理。而ClassicMartini是一个开箱即用的struct,添加了路由服务和一些默认的中间件。
Context是http请求上下文,可以在这里使用service注入。
二 主流程
在Golang标准库中,一个最简单的http服务器的代码是这样子的:
http.HandleFunc(“/“, func(w http.ResponseWriter, r *http.Request) {
})
http.ListenAndServe(“localhost:9000”, nil)
一段最简单的martini服务器代码为:
m := martini.Classic()
m.Run()
这段代码的初始化流程如下:
查看标准库的官方文档,ListenAndServe函数在接收到HTTP请求时会调用第二个参数的ServeHTTP(ResponseWriter, *Request)方法,Martini的ServeHTTP方法流程如下:
应当说还是相当清楚的。