文章目录

  • 前言
  • 安装
  • 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

关键代码解析

  1. 创建一个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...)
}
  1. 关于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

  1. 关于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

  1. 注册路由

这里很简单了就是注册用户路由到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,
}
  1. 构建请求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)
  1. 启动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相关推荐

  1. web框架:Iris快速入门

    web框架:Iris快速入门 1 介绍及安装 介绍 Iris是一款用Go开发的web应用框架,被称为速度最快的Go后端开发框架. 官网地址:https://www.iris-go.com/ 中文教程地 ...

  2. AlexeyAB DarkNet YOLOv3框架解析与应用实践(六)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(六) Tiny Darknet 听过很多人谈论SqueezeNet. SqueezeNet很酷,但它只是优化参数计数.当大多数高质量的 ...

  3. AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(五) RNNs in Darknet 递归神经网络是表示随时间变化的数据的强大模型.为了更好地介绍RNNs,我强烈推荐Andrej K ...

  4. AlexeyAB DarkNet YOLOv3框架解析与应用实践(四)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(四) Nightmare 从前,在一所大学的大楼里,西蒙尼亚.维达第和齐瑟曼有一个很好的主意,几乎和你现在坐的大楼完全不同.他们想,嘿 ...

  5. AlexeyAB DarkNet YOLOv3框架解析与应用实践(三)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(三) ImageNet分类 您可以使用Darknet为1000级ImageNet挑战赛分类图像.如果你还没有安装Darknet,你应该 ...

  6. AlexeyAB DarkNet YOLOv3框架解析与应用实践(二)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(二) 版本3有什么新功能? YOLOv3使用了一些技巧来改进训练和提高性能,包括:多尺度预测.更好的主干分类器等等.全部细节都在我们的 ...

  7. AlexeyAB DarkNet YOLOv3框架解析与应用实践(一)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(一) Darknet: C语言中的开源神经网络 Darknet是一个用C和CUDA编写的开源神经网络框架.它速度快,易于安装,支持CP ...

  8. yolov3(三:算法框架解析)

    应用见: https://blog.csdn.net/Darlingqiang/article/details/103889245 https://blog.csdn.net/Darlingqiang ...

  9. WebKit 框架解析

    WebKit框架解析(一)-- 基本概览及WKWebView(一) WebKit框架解析(二)-- 基本概览及WKWebView(二)

最新文章

  1. 数造未来——探索大数据的应用价值
  2. 网易云游戏来了:手机电脑电视随时接入可玩,高流畅度低延迟,还能跨终端无缝切换...
  3. 统计学习方法---拉格朗日对偶新性
  4. 模拟信号与数字信号以及数模隔离简介
  5. tinyhttpd-0.1.0_hacking
  6. Light OJ 1373 Strongly Connected Chemicals 二分匹配最大独立集
  7. Spring boot统一日志记录
  8. 如何添加自定义icon
  9. VMware vCloud® Suite 5.5功能介绍
  10. 千博HTML5自适应企业网站系统 v2021 Build0622
  11. delete kubectl pod_使用kubectl管理k8s集群(三十)
  12. spring mvc 自定义编辑器
  13. 最新基于高德地图的android进阶开发(5)地图的基本操作、事件监听、用户UI、图层选择等
  14. MATLAB数字滤波器波形设计
  15. 视频截取程序matlab,通过matlab截取视频
  16. php的parent_php中parent::是如何使用的?
  17. 生成带微信头像的用户二维码
  18. 计算机原理探究第一部分教案,高中信息技术《计算机结构原理初步》教案
  19. 方法总结分享|金融时间序列联动相关及风险溢出
  20. 又来汇丰软件(广东)的帖子了。。。

热门文章

  1. Excel技巧—自动标记颜色条件格式的妙用
  2. android测试测试模拟器,模拟和测试其他浏览器
  3. javascript延迟加载方式
  4. 在php中字符串是什么意思,PHP的字符串函数
  5. 外出前提前跟领导报备,安排工作备份人
  6. c# 访问共享文件夹 用户名或密码不正确 及 拒绝访问
  7. P3073 Tractor
  8. oracle nvl 使用教程
  9. [案例3-4]学生投票系统
  10. 宠物衣服类和宠物玩具类上架亚马逊CPC检测标准