2019独角兽企业重金招聘Python工程师标准>>>

在入口函数main()default分支中,对路由进行了注册,现在分析下。

##main()中路由注册相关代码

源码:

httpRouter := httptreemux.New()
// Blog and pages as http
server.InitializeBlog(httpRouter)
server.InitializePages(httpRouter)
// Admin as http
server.InitializeAdmin(httpRouter)
// Start http server
log.Println("Starting server without HTTPS support. Please enable HTTPS in " + filenames.ConfigFilename + " to improve security.")
log.Println("Starting http server on port " + httpPort + "...")
err := http.ListenAndServe(httpPort, httpRouter)
if err != nil {log.Fatal("Error: Couldn't start the HTTP server:", err)
}

###httptreemux.New()

func New() *TreeMux {root := &node{path: "/"}return &TreeMux{root: root,NotFoundHandler:         http.NotFound,MethodNotAllowedHandler: MethodNotAllowedHandler,HeadCanUseGet:           true,RedirectTrailingSlash:   true,RedirectCleanPath:       true,RedirectBehavior:        Redirect301,RedirectMethodBehavior:  make(map[string]RedirectBehavior),PathSource:              RequestURI,}
}

可以看到他返回了一个实例化的结构体TreeMux,这个结构体注册了根路径/,此外还包含一些默认的handle,如http.NotFound:

// NotFound replies to the request with an HTTP 404 not found error.
func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }

###server.InitializeBlog(httpRouter)

func InitializeBlog(router *httptreemux.TreeMux) {// For indexrouter.GET("/", indexHandler)router.GET("/:slug/", postHandler)router.GET("/page/:number/", indexHandler)// For authorrouter.GET("/author/:slug/", authorHandler)router.GET("/author/:slug/:function/", authorHandler)router.GET("/author/:slug/:function/:number/", authorHandler)// For tagrouter.GET("/tag/:slug/", tagHandler)router.GET("/tag/:slug/:function/", tagHandler)router.GET("/tag/:slug/:function/:number/", tagHandler)// For serving asset filesrouter.GET("/assets/*filepath", assetsHandler)router.GET("/images/*filepath", imagesHandler)router.GET("/content/images/*filepath", imagesHandler) // This is here to keep compatibility with Ghostrouter.GET("/public/*filepath", publicHandler)
}

这里使用了route.GET()函数注册路由,我们看下router.GET("/", indexHandler):

// Syntactic sugar for Handle("GET", path, handler)
func (t *TreeMux) GET(path string, handler HandlerFunc) {t.Handle("GET", path, handler)
}

t.Handle("GET", path, handler):

func (t *TreeMux) Handle(method, path string, handler HandlerFunc) {if path[0] != '/' {panic(fmt.Sprintf("Path %s must start with slash", path))}addSlash := falseif len(path) > 1 && path[len(path)-1] == '/' && t.RedirectTrailingSlash {addSlash = truepath = path[:len(path)-1]}//将path注册到root子节点中去,并返回子节点的引用node := t.root.addPath(path[1:], nil)if addSlash {node.addSlash = true}//最终注册路由node.setHandler(method, handler)
}

node.setHandler(method, handler):

func (n *node) setHandler(verb string, handler HandlerFunc) {if n.leafHandler == nil {n.leafHandler = make(map[string]HandlerFunc)}_, ok := n.leafHandler[verb]if ok {panic(fmt.Sprintf("%s already handles %s", n.path, verb))}n.leafHandler[verb] = handler
}

剩下的路由注册server.InitializeBlog(httpRouter),server.InitializePages(httpRouter),server.InitializeAdmin(httpRouter)都大同小异。

这里只是介绍了路由注册的整体流程,其中最复杂的地方是func (t *TreeMux) Handle(method, path string, handler HandlerFunc)中的node := t.root.addPath(path[1:], nil)函数,不过源码有详细的注释,有兴趣的自行研究。

转载于:https://my.oschina.net/fmnisme/blog/502715

Journey源码分析四:url路由相关推荐

  1. Spring 源码分析(四) ——MVC(二)概述

    随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) from:Spring 源码分析(四) --MVC(二)概述 - 水门-kay的个人页面 - OSCHINA ...

  2. Journey源码分析三:模板编译

    2019独角兽企业重金招聘Python工程师标准>>> 在Journey源码分析二:整体启动流程中提到了模板编译,这里详细说下启动流程 看下templates.Generate()源 ...

  3. ABP源码分析四十七:ABP中的异常处理

    ABP源码分析四十七:ABP中的异常处理 参考文章: (1)ABP源码分析四十七:ABP中的异常处理 (2)https://www.cnblogs.com/1zhk/p/5538983.html (3 ...

  4. 【投屏】Scrcpy源码分析四(最终章 - Server篇)

    Scrcpy源码分析系列 [投屏]Scrcpy源码分析一(编译篇) [投屏]Scrcpy源码分析二(Client篇-连接阶段) [投屏]Scrcpy源码分析三(Client篇-投屏阶段) [投屏]Sc ...

  5. gSOAP 源码分析(四)

    gSOAP 源码分析(四) 2012-6-2 邵盛松 前言 本文主要说明gSOAP中对Client的认证分析 gSOAP中包含了HTTP基本认证,NTLM认证等,还可以自定义SOAP Heard实现认 ...

  6. 云客Drupal源码分析之Url和Link

    各位<云客drupal8源码分析>系列的读者: 本系列分享希望帮助大家理解drupal8底层原理,并缩短学习时间,但部分重点内容在博客仅发布前言和目录,这是因为:drupal在国外如此流行 ...

  7. 谷歌chrome浏览器的源码分析(四)

    上一次说到需要调用这个OpenURLFromTab函数,那么这个函数是做什么的呢?从名称上可能猜到它是打开网页,但是是从目前TAB页里打开呢?还是新建一个?或者使用每个TAB页一个进程呢?这些疑惑,只 ...

  8. 【转】ABP源码分析四十七:ABP中的异常处理

    ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...

  9. 【转】ABP源码分析四:Configuration

    核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...

最新文章

  1. golang学习笔记01
  2. 如何将dmp文件里的某张表导入oracle数据库
  3. 性能测试Jmeter吞吐量控制器使用总结
  4. [HttpPost] vs [AcceptVerbs(HttpVerbs.Post)]
  5. 在ASP中常见的错误80004005信息和解决办法
  6. ibatis中输入/输出各种类型的参数分析及#与$区别 (转)
  7. pc 页面在移动端怎么获取放大倍数、_逆冬:移动端排名应该怎么做?两种匹配移动端实战排名干货分享!...
  8. Android模仿新浪微博(写微博界面)
  9. DBA:这有一份对接NBU备份故障排除指南,请查收!
  10. ESD静电二极管封装规格,详细介绍
  11. PSPICE仿真数据转MATLAB
  12. MATLAB的MCC命令
  13. 推荐交互设计师阅读的一本书
  14. 端午节了,了解粽子的起源
  15. 工业网关下工业自动化设备远程监控解决方案
  16. 路径规划算法C++实现(三)--DWA
  17. hexo categories和tags页面不显示解决办法
  18. SMBIOS信息概述 – DMI
  19. socket.io不错的websocket
  20. 状态代码255 必须重启服务器,kubelet服务启动失败,错误代码255

热门文章

  1. 在Ubuntu下FFmpeg编译,支持x264和x265(HECV)
  2. iOS 之 IQKeyboardManager 解决使用UITableView 界面上移问题
  3. OpenCV-Python:K值聚类
  4. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素
  5. 沃尔沃加入英伟达阵营 2021年开卖自动驾驶汽车
  6. Linux中断处理驱动程序编写【转】
  7. 写了个Python脚本监控nginx进程
  8. Tech.Ed2005 讲义下载地址
  9. git 设置有效目录_如何有效使用Git
  10. angular搭建项目步骤_建立健康的Angular项目应采取的步骤