路由匹配探秘

先上源码:

class Flask(_PackageBoundObject):

    def wsgi_app(self, environ, start_response):
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                ctx.push()
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:  # noqa: B001
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

从上面的代码中,并没有直接发现路由匹配相关的逻辑,那问题来了,路由匹配到底藏在哪里?其实关键在于ctx.push()操作,ctx为全局变量request上下文的实例,ctx.push()将其进行入栈操作,放在栈顶。现贴出ctx.push()的相关逻辑:

通过调用链可知,self.url_adapter其实就是werkzeug.routing的MapAdapter类的实例化对象,我们来看看MapAdapter的match方法是如何实现的:

由代码可见,路由匹配发生在werkzeug的routing模块中,通过对map对象中的_rules的迭代,来匹配url以及methods,并通过不同的异常,来通知上层,即app模块中Flask类的wsgi_app函数,如果发生异常,则生成对应的response,返回给客户端,如果未发生异常,则通过Flask类的full_dispatch_request函数和request的endpoint属性来分发请求的views函数,而endpoint和view_func的对应关系保存在Flask类的view_functions中。

Last updated

Was this helpful?