【Go原理】go语言两行代码创建http服务

文章目录


【Go原理】go语言两行代码创建http服务

由简单http服务引出问题

源码如下:创建一个在8080端口服务的程序

package main

import "net/http"

func main() {
	//TODO 添加路由过程处理
	http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("Hello World!"))})
	//TODO 启动服务
	http.ListenAndServe(":8080", nil)
}

我们虽然看似非常简单的就添加了路由处理回调以及启动服务,但是我们感觉啥也没懂啊,就是很空洞,不清楚这个具体过程的那种空洞感,导致我初学时虽然用起来简单,但我属于那种不弄清楚原理就记不住的那一类人,故写了一个总结

浅析原理

Handler接口

作用

这个接口存在的目的主要是为了让所有的回调函数处理动作统一,也就是只要实现了这个接口,就可以作为回调函数传入到一些地方使用。

接口的源码:接口内定义了ServeHTTP方法

【Go原理】go语言两行代码创建http服务

ServeMux类

作用

go语言内置实现的Handler用于主路由,将服务转法给他内部注册的其他Handler。具体到使用过程中就是,我可以设置 '/hello' 这个前缀名的处理逻辑函数为一个自定义的Handler,也可添加处理其他前缀的Handler。

具体可看下面图片:

【Go原理】go语言两行代码创建http服务

初始化

初始化只需要调用http包的NewServeMux即可

具体的ServeMux类的成员对现在的我来说还难以理解,所以这里只需要调用它提供的方法得到具体的类的实例即可。

【Go原理】go语言两行代码创建http服务

根据以上源码来看,我们也可以自己直接new 一个ServeMux

基本方法

  1. Handle方法
    【Go原理】go语言两行代码创建http服务
    需要传入字符串和一个实现Handler接口的类来进行注册。

  2. HandleFunc方法

    【Go原理】go语言两行代码创建http服务
    只需要传入字符串和一个特定类型的函数即可。

需要注意:HandleFunc方法实际还是调用的Handle方法,只不过在内部多了一步把函数转成Handler的过程。

对应以下源码:

【Go原理】go语言两行代码创建http服务

创建了一个类型,并实现了Hanlder接口

【Go原理】go语言两行代码创建http服务

Serve类

作用

用于给Handler启动对应端口的服务。

初始化

Serve是一个结构体,里面有很多成员,但我们需要初始化的成员一般只有这两个:Addr和Handler。

【Go原理】go语言两行代码创建http服务

Addr用于指定服务的端口号,Handler用于指定处理该端口号请求的对象。

基本方法

基本方法:ListenAndServe()调用该方法后可以对Addr所表示的端口进行服务,然后是调用Handler进行服务。

简单使用过程:

package main

import "net/http"

func main() {
	s := &http.Server{Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello world!"))
	})}
	//TODO 启动服务
	s.ListenAndServe()
}

现在你只要输入8080端口,所有的服务都是返回Hello world了,原因是你把主路由逻辑用了自己写的Handler,而内部的ServeMux能够提供将请求处理转发,而你自己写的Handler则未有这个逻辑

回到最开始的源代码

有了前面对三个基本结构的剖析,那么现在最开始那两行代码再跳转到内部源码就能够很清晰的知道是什么个情况了!

	//TODO 添加路由过程处理
	http.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("Hello World!"))})
	//TODO 启动服务
	http.ListenAndServe(":8080", nil)

都是基于DefaultServeMux

DefaultServeMux 就是http这个文件中定义的对外导出的变量,而这个变量套了一层,实际上还是ServeMux类型。所以DefaultServeMux 就是http包事先给你默认创建好的ServeMux变量。

【Go原理】go语言两行代码创建http服务

知道这个有什么用呢?

我们之前讨论的所有服务建立过程和响应请求过程,都是通过类的方法来进行,而我们最开始的两行代码却只需要调用两个函数,你难道不感到奇怪吗?

知道了http包里面有个默认的变量,那这个疑问就迎刃而解了,当我们调用这两个函数的时候,实际上就是在http包里面调用DefaultServeMux或者Serve类的方法而已

http.HandleFunc()

源码:

【Go原理】go语言两行代码创建http服务

http.ListenAndServe()

源码:

当handler传值为nil时,初始化Server的Handler为DefaultServeMux

【Go原理】go语言两行代码创建http服务

上一篇:手写一个 Flutter 持久化的会话管理器


下一篇:Go语言net/http包使用详细介绍