路由匹配探秘
先上源码:
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?