Tornado 高并发源码分析之三--- Application 对象

【Tornado 高并发源码分析之三--- Application 对象】于今腐草无萤火,终古垂杨有暮鸦。这篇文章主要讲述Tornado 高并发源码分析之三--- Application 对象相关的知识,希望能为你提供帮助。
 
Application 对象主要工作: 服务器启动时: 1、在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象   服务器运行时: 2、在请求到来,将 HTTPServer 封装好的HTTPRequest 传入_RequestDispatcher对象,_RequestDispatcher对象根据传入的 HTTPRequest 使用URLSpec解析匹 match 正则匹配找到对应的 RequestHandler ,执行它的 _execute 方法   Application设计优点 1、Application 本身不处理数据,只是封装 URL , 解析请求的 URL, 分发到 URL 相对应的 RequestHandler 去执行具体操作   以下为源码分析,省略了一部分代码,只取关键部分显示

1 class Application(httputil.HTTPServerConnectionDelegate): 2 # 继承自httputil.HTTPServerConnectionDelegate, 其实HTTPServerConnectionDelegate只是一种类似于协议的东西,只要继承自他就可以了,方便其他地方可以调用 isinstanct 来判断, 3 def __init__(self, handlers=None, default_host="", transforms=None, **settings): 4 #完成 url映射 和 setting相关的设置 5 6self.handlers = [] 7self.named_handlers = {} 8self.settings = settings#导入设置的参数 9 10if handlers: 11self.add_handlers(".*$", handlers)#将URL 和 Handler 映射封装成 URLSpec 对象 12 13if self.settings.get(‘autoreload‘):#设置自动重启 14from tornado import autoreload 15autoreload.start() 16 17 18 def add_handlers(self, host_pattern, host_handlers): 19#将 url 和 handler 封装成URLSpec 20for spec in host_handlers: 21if isinstance(spec, (tuple, list)): 22assert len(spec) in (2, 3, 4) 23spec = URLSpec(*spec)#封装成 URLSpec 对象 24handlers.append(spec) 25if spec.name: 26if spec.name in self.named_handlers: 27app_log.warning( 28"Multiple handlers named %s; replacing previous value", 29spec.name) 30self.named_handlers[spec.name] = spec#将url 和 handler隐射封装起来 31 32 def __call__(self, request): 33# 在这里巧用了__call__方法,当一个application 新建的时候,将会被动调用,这个是在请求信息已经接收完毕,已经封装成 HTTPRequest 对象之后,执行用户的 RequestHandler 对象的get、post方法 34dispatcher = _RequestDispatcher(self, None) 35dispatcher.set_request(request)#将封装好的HTTPRequest对象(此时数据已经接收完毕),设置进_RequestDispatcher中, 36return dispatcher.execute()#执行用户的 RequestHandler 对象的get、post方法,对数据处理,并返回

1 class _RequestDispatcher(httputil.HTTPMessageDelegate): 2 正在用来执行用户写的 RequestHandler 对象里面的get、post等方法 3 def set_request(self, request): 4self.request = request#设置request 5self._find_handler()#根据request查找url匹配 6self.stream_request_body = _has_stream_request_body(self.handler_class) 7 8 def _find_handler(self): 9 # 10app = self.application 11handlers = app._get_host_handlers(self.request)#从request中获取头信息 12if not handlers: 13self.handler_class = RedirectHandler 14self.handler_kwargs = dict(url="http://" + app.default_host + "/") 15return 16for spec in handlers:#遍历url 匹配的类 17match = spec.regex.match(self.request.path)#url路径匹配 18if match: 19self.handler_class = spec.handler_class#获取url匹配的我们写的自定义的RequestHandler类 20self.handler_kwargs = spec.kwargs 21if spec.regex.groups: 22if spec.regex.groupindex: 23self.path_kwargs = dict( 24(str(k), _unquote_or_none(v)) 25for (k, v) in match.groupdict().items()) 26else: 27self.path_args = [_unquote_or_none(s) 28for s in match.groups()] 29return 30 31 32 def execute(self): 33self.handler = self.handler_class(self.application, self.request, **self.handler_kwargs)#获取我们自定义的RequestHandler类实例,传递参数 34 35if self.stream_request_body:#先创建一个future 对象 36self.handler._prepared_future = Future() 37 38self.handler._execute(transforms, *self.path_args, **self.path_kwargs)#执行我们自定义的,继承RequestHandler类的 _execute 函数, 所以最后我们的写的get post方法,还是在自己的那个类的_execute方法中调用执行的 39 40return self.handler._prepared_future#返回自定义的RequestHandler future 对象

 

    推荐阅读