Go 框架解析 -iris
文章目录
- 前言
- 安装
- iris的生命周期
- 关键代码解析
- 结语
- 文献
前言
之前已经发过一篇过于beego的文章《golang框架解析-beego》,今天带来的是go框架iris的解析,主要讲解iris框架的一个生命周期过程。
在读这篇文章之前,如果没看过《golang框架解析-beego》的可以先去看看,因为《golang框架解析-beego》有讲关于go如何启动一个http server,这个知识点对理解本篇文章有很大的帮助。
安装
使用glide安装:
glide get github.com/kataras/iris
glide get github.com/kataras/golog
启动一个简单的iris http服务:
//main.go
package mainimport "github.com/kataras/iris"func main() {app := iris.Default()app.Get("/ping", func(ctx iris.Context) {ctx.JSON(iris.Map{"message": "pong",})})app.Run(iris.Addr(":8888"))
}
iris的生命周期
图片过大 建议查看原图片链接 http://cdn.tigerb.cn/20190628234814.png
上图是我在读iris代码时,整理的iris框架的一个生命周期流程图,内容比较多。总的来说划分为四个大的部分:
橙色部分:
初始化iris.Application:
- 创建iris.Application
- 创建APIBuilder(app.Get()等方法的路由都是注册到这里)
- 创建Router(每个http请求都是通过router处理的)
蓝色部分:
注册路由到app.APIBuilder
紫色部分:
初始化一个http.Server
绿色部分:
构建路由handler&启动http server:
- 注册 app.APIBuilder.routes 的路由到 app.Router.requestHandler
- 注册 app.APIBuilder 到 app.Router.routesProvider
- 启动 http server
关键代码解析
- 创建一个iris Application
// Application 首先看看我们的iris Application结构体组成
type Application struct {// 我们的路由都注册到了 APIBuilder*router.APIBuilder// *router.Router 实现了ServeHTTP方法 并且最终赋值给了&http.server{}.Handler*router.Router// 请求上下文池子ContextPool *context.Pool// 配置项config *Configuration// 日志logger *golog.Logger// 视图view view.View// 执行一次的onceonce sync.Once// 互斥锁mu sync.MutexHosts []*host.SupervisorhostConfigurators []host.Configurator
}// 创建了一个iris应用实例
// 为什么不直接New呢?
// 因为Default里面注册了两个handle
// 1. recover panic的方法,
// 2. 请求日志
app := iris.Default()func Default() *Application {app := New()// 合成复用*APIBuilder的Useapp.Use(recover.New())// 合成复用*APIBuilder的Useapp.Use(requestLogger.New())return app
}// app := New() 得到的结构体
app := &Application{config: &config,logger: golog.Default,// 很关键:我们的路由都注册到了 APIBuilderAPIBuilder: router.NewAPIBuilder(),// 很关键:*router.Router 实现了ServeHTTP方法 并且最终赋值给了&http.server{}.HandlerRouter: router.NewRouter(),
}// 注册api请求的中间件
func (api *APIBuilder) Use(handlers ...context.Handler) {api.middleware = append(api.middleware, handlers...)
}
- 关于router.NewAPIBuilder()
APIBuilder的routes属性很关键,最终的我们定义的路由都是注册到了这里。
// APIBuilder
api := &APIBuilder{macros: macro.Defaults,errorCodeHandlers: defaultErrorCodeHandlers(),reporter: errors.NewReporter(),relativePath: "/",// 最终的我们定义的路由都是注册到了这里routes: new(repository),
}// repository的结构
type repository struct {routes []*Route
}
结论:用户路由注册到了app.APIBuilder.routes
- 关于router.NewRouter()
router.NewRouter()返回的是一个&Router{}指针,&Router{}有三个很关键的属性和一个ServeHTTP成员方法。
三个关键的属性:
- ainHandler http.HandlerFunc
- requestHandler RequestHandler
- routesProvider RoutesProvider
我们再看成员方法ServeHTTP实现了ServeHTTP(w http.ResponseWriter, r *http.Request)方法,就是accept请求之后就会执行这个方法,我们看看具体方法内容。
// implement ServeHTTP
func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 所以这里可以看出accept请求之后会执行mainHandlerrouter.mainHandler(w, r)
}
func NewRouter() *Router { return &Router{} }type Router struct {mu sync.MutexrequestHandler RequestHandler// 每次http请求都会执行mainHandlermainHandler http.HandlerFuncwrapperFunc func(http.ResponseWriter, *http.Request, http.HandlerFunc)cPool *context.Pool rroutesProvider RoutesProvider
}// implement ServeHTTP
func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 每次http请求都会执行mainHandlerrouter.mainHandler(w, r)
}
结论:每次http请求都会执行mainHandler
- 注册路由
这里很简单了就是注册用户路由到app.APIBuilder.routes
//router
func (api *APIBuilder) Get(relativePath string, handlers ...context.Handler) *Route {return api.Handle(http.MethodGet, relativePath, handlers...)
}route := &Route{Name: defaultName,Method: method,methodBckp: method,Subdomain: subdomain,tmpl: tmpl,Path: path,Handlers: handlers,MainHandlerName: mainHandlerName,FormattedPath: formattedPath,
}
- 构建请求handler
//启动路由
app.Run()
⬇️
// 构建
app.Build()
⬇️
// 构建路由
app.Router.BuildRouter(app.ContextPool, routerHandler, app.APIBuilder, false)
⬇️
// 构建请求Handler
// 把app.APIBuilder注册的api注册到了requestHandler里
// 因为我们在下面发现请求都是从router.requestHandler去处理的
requestHandler.Build(routesProvider)
⬇️
// 赋值
router.requestHandler = requestHandler
router.routesProvider = routesProvider
⬇️
// the important 没错很重要的地方mainHandler被赋值的地方
// 也就是accpet请求实际执行的代码
// 真相就在这
// the important
router.mainHandler = func(w http.ResponseWriter, r *http.Request) {// 构建请求上下文ctx := cPool.Acquire(w, r)// 处理请求router.requestHandler.HandleRequest(ctx)// 释放请求上下文cPool.Release(ctx)
}
⬇️
// 实际处理请求饿地方
// 路由的匹配就是这里了
func (h *routerHandler) HandleRequest(ctx context.Context)
- 启动HTTP Server
最后我们就是启动这个http server了,这里和绝大多数golang的http服务启动基本一致。
// 赋值http服务的ip+port
iris.Addr(":8888")
⬇️
//创建http.Server并启动服务的匿名方法
func Addr(addr string, hostConfigs ...host.Configurator) Runner {return func(app *Application) error {return app.NewHost(&http.Server{Addr: addr}).Configure(hostConfigs...).ListenAndServe()}
}
⬇️
// app.NewHost(&http.Server{Addr: addr})
// 就是这里赋值app.Router给http.Server的Handler的
if srv.Handler == nil {srv.Handler = app.Router
}
⬇️
// 启动服务
su.Server.Serve(l)
⬇️
// accept请求
l.Accept()
⬇️
// 启动一个goroutine处理请求
go c.serve(ctx)
⬇️
// 最终至此真相都大白了
serverHandler{c.server}.ServeHTTP(w, w.req)
结语
最后我们再简单的回顾下上面的流程:
文献
https://mp.weixin.qq.com/s/-xhhuPkutY1-G4_NugNotQ
Go 框架解析 -iris相关推荐
- web框架:Iris快速入门
web框架:Iris快速入门 1 介绍及安装 介绍 Iris是一款用Go开发的web应用框架,被称为速度最快的Go后端开发框架. 官网地址:https://www.iris-go.com/ 中文教程地 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(六)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(六) Tiny Darknet 听过很多人谈论SqueezeNet. SqueezeNet很酷,但它只是优化参数计数.当大多数高质量的 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(五) RNNs in Darknet 递归神经网络是表示随时间变化的数据的强大模型.为了更好地介绍RNNs,我强烈推荐Andrej K ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(四)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(四) Nightmare 从前,在一所大学的大楼里,西蒙尼亚.维达第和齐瑟曼有一个很好的主意,几乎和你现在坐的大楼完全不同.他们想,嘿 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(三)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(三) ImageNet分类 您可以使用Darknet为1000级ImageNet挑战赛分类图像.如果你还没有安装Darknet,你应该 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(二)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(二) 版本3有什么新功能? YOLOv3使用了一些技巧来改进训练和提高性能,包括:多尺度预测.更好的主干分类器等等.全部细节都在我们的 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(一)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(一) Darknet: C语言中的开源神经网络 Darknet是一个用C和CUDA编写的开源神经网络框架.它速度快,易于安装,支持CP ...
- yolov3(三:算法框架解析)
应用见: https://blog.csdn.net/Darlingqiang/article/details/103889245 https://blog.csdn.net/Darlingqiang ...
- WebKit 框架解析
WebKit框架解析(一)-- 基本概览及WKWebView(一) WebKit框架解析(二)-- 基本概览及WKWebView(二)
最新文章
- 数造未来——探索大数据的应用价值
- 网易云游戏来了:手机电脑电视随时接入可玩,高流畅度低延迟,还能跨终端无缝切换...
- 统计学习方法---拉格朗日对偶新性
- 模拟信号与数字信号以及数模隔离简介
- tinyhttpd-0.1.0_hacking
- Light OJ 1373 Strongly Connected Chemicals 二分匹配最大独立集
- Spring boot统一日志记录
- 如何添加自定义icon
- VMware vCloud® Suite 5.5功能介绍
- 千博HTML5自适应企业网站系统 v2021 Build0622
- delete kubectl pod_使用kubectl管理k8s集群(三十)
- spring mvc 自定义编辑器
- 最新基于高德地图的android进阶开发(5)地图的基本操作、事件监听、用户UI、图层选择等
- MATLAB数字滤波器波形设计
- 视频截取程序matlab,通过matlab截取视频
- php的parent_php中parent::是如何使用的?
- 生成带微信头像的用户二维码
- 计算机原理探究第一部分教案,高中信息技术《计算机结构原理初步》教案
- 方法总结分享|金融时间序列联动相关及风险溢出
- 又来汇丰软件(广东)的帖子了。。。