前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang源码分析(37)martini

golang源码分析(37)martini

作者头像
golangLeetcode
发布2022-08-02 17:12:18
3680
发布2022-08-02 17:12:18
举报
文章被收录于专栏:golang算法架构leetcode技术php

Martini的官方文档中提到Martini完全兼容http.HandlerFunc接口.,底下谈到martini.Context的初始化就会有说明。

先来看看Martini的结构体。

代码语言:javascript
复制
// Martini represents the top level web application. inject.Injector methods can be invoked to map services on a global level.
type Martini struct {
    inject.Injector
    handlers []Handler
    action   Handler
    logger   *log.Logger
}

inject.Injectorinject接口实例,Martini高度依赖injecthandlers是切片存储Hander类型,Handler是自定义类型。

代码语言:javascript
复制
type Handler interface{}

Martini有两种处理器,中间件处理器和请求处理器。中间件处理器通过Use方法将中间件追加保存到handlers切片中,请求处理器需要搭配路由进行存储。

初始化

为了更快速的启用Martini, martini.Classic() 提供了一些默认的方便Web开发的工具:

代码语言:javascript
复制
  m := martini.Classic()
  // ... middleware and routing goes here
  m.Run()

下面是Martini核心已经包含的功能 martini.Classic():

  • Request/Response Logging (请求/响应日志) - martini.Logger
  • Panic Recovery (容错) - martini.Recovery
  • Static File serving (静态文件服务) - martini.Static
  • Routing (路由) - martini.Router

下面的这些服务已经被包含在核心Martini中: martini.Classic():

  • *log.Logger - Martini的全局日志.
  • martini.Context - http request context (请求上下文).
  • martini.Params - map[string]string of named params found by route matching. (名字和参数键值对的参数列表)
  • martini.Routes - Route helper service. (路由协助处理)
  • http.ResponseWriter - http Response writer interface. (响应结果的流接口)
  • *http.Request - http Request. (http请求)

martini.Context是每次请求的上下文。

代码语言:javascript
复制
// Context represents a request context. Services can be mapped on the request level from this interface.
type Context interface {
    inject.Injector
    // Next is an optional function that Middleware Handlers can call to yield the until after
    // the other Handlers have been executed. This works really well for any operations that must
    // happen after an http request
    Next()
    // Written returns whether or not the response for this context has been written.
    Written() bool
}

它是什么时候被创建的呢?还记得《理解go的function types》吗?

代码语言:javascript
复制
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)

martini.go实现了ServerHTTP方法。

代码语言:javascript
复制
// ServeHTTP is the HTTP Entry point for a Martini instance. Useful if you want to control your own HTTP server.
func (m *Martini) ServeHTTP(res http.ResponseWriter, req *http.Request) {
    m.createContext(res, req).run()
}

因为Martini实现了http.HandlerFunc接口,所以它可以很简单的应用到现有Go服务器的子集中。

代码语言:javascript
复制
package hello

import (
  "net/http"
  "github.com/go-martini/martini"
)

func init() {
  m := martini.Classic()
  m.Get("/", func() string {
    return "Hello world!"
  })
  http.Handle("/", m)
}

martini.Context的实例m.context就是在go服务器初始化的时候通过ServeHTTP被创建的。

我们已经知道Martini如何应用到Go服务器的子集,那么当服务器运行的时候,处理器是如何被执行的呢?

运行

我们看看context结构体

代码语言:javascript
复制
type context struct {
    inject.Injector
    handlers []Handler
    action   Handler
    rw       ResponseWriter
    index    int
}

func (c *context) handler() Handler {
    if c.index < len(c.handlers) {
        return c.handlers[c.index]
    }
    if c.index == len(c.handlers) {
        return c.action
    }
    panic("invalid index for context handler")
}

func (c *context) Next() {
    c.index += 1
    c.run()
}

func (c *context) Written() bool {
    return c.rw.Written()
}

func (c *context) run() {
    for c.index <= len(c.handlers) {
        _, err := c.Invoke(c.handler())
        if err != nil {
            panic(err)
        }
        c.index += 1

        if c.Written() {
            return
        }
    }
}

context实现了Context接口,自然也组合了inject.Injector。处理器处理请求的时候通过run()循环遍历调用handlers中的所有中间件和路由处理方法。

看到这里是不是发现一个很眼熟的函数Invoke(),没错又是injectInvoke()

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化
  • 运行
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档