Application 对象主要工作:
服务器启动时:
1、在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象
 
服务器运行时:
2、在请求到来,将 HTTPServer 封装好的HTTPRequest 传入_RequestDispatcher对象,_RequestDispatcher对象根据传入的 HTTPRequest 使用URLSpec解析匹 match 正则匹配找到对应的 RequestHandler ,执行它的 _execute 方法
 
Application设计优点
1、Application 本身不处理数据,只是封装 URL , 解析请求的 URL, 分发到 URL 相对应的 RequestHandler 去执行具体操作
 
以下为源码分析,省略了一部分代码,只取关键部分显示
 class Application(httputil.HTTPServerConnectionDelegate):
# 继承自httputil.HTTPServerConnectionDelegate, 其实HTTPServerConnectionDelegate只是一种类似于协议的东西,只要继承自他就可以了,方便其他地方可以调用 isinstanct 来判断,
def __init__(self, handlers=None, default_host="", transforms=None, **settings):
#完成 url映射 和 setting相关的设置 self.handlers = []
self.named_handlers = {}
self.settings = settings #导入设置的参数 if handlers:
self.add_handlers(".*$", handlers) #将URL 和 Handler 映射封装成 URLSpec 对象 if self.settings.get('autoreload'): #设置自动重启
from tornado import autoreload
autoreload.start() def add_handlers(self, host_pattern, host_handlers):
#将 url 和 handler 封装成URLSpec
for spec in host_handlers:
if isinstance(spec, (tuple, list)):
assert len(spec) in (2, 3, 4)
spec = URLSpec(*spec) #封装成 URLSpec 对象
handlers.append(spec)
if spec.name:
if spec.name in self.named_handlers:
app_log.warning(
"Multiple handlers named %s; replacing previous value",
spec.name)
self.named_handlers[spec.name] = spec #将url 和 handler隐射封装起来 def __call__(self, request):
# 在这里巧用了__call__方法,当一个application 新建的时候,将会被动调用,这个是在请求信息已经接收完毕,已经封装成 HTTPRequest 对象之后,执行用户的 RequestHandler 对象的get、post方法
dispatcher = _RequestDispatcher(self, None)
dispatcher.set_request(request) #将封装好的HTTPRequest对象(此时数据已经接收完毕),设置进_RequestDispatcher中,
return dispatcher.execute() #执行用户的 RequestHandler 对象的get、post方法,对数据处理,并返回
 class _RequestDispatcher(httputil.HTTPMessageDelegate):
正在用来执行用户写的 RequestHandler 对象里面的get、post等方法
def set_request(self, request):
self.request = request #设置request
self._find_handler() #根据request查找url匹配
self.stream_request_body = _has_stream_request_body(self.handler_class) def _find_handler(self):
#
app = self.application
handlers = app._get_host_handlers(self.request) #从request中获取头信息
if not handlers:
self.handler_class = RedirectHandler
self.handler_kwargs = dict(url="http://" + app.default_host + "/")
return
for spec in handlers: #遍历url 匹配的类
match = spec.regex.match(self.request.path) #url路径匹配
if match:
self.handler_class = spec.handler_class #获取url匹配的我们写的自定义的RequestHandler类
self.handler_kwargs = spec.kwargs
if spec.regex.groups:
if spec.regex.groupindex:
self.path_kwargs = dict(
(str(k), _unquote_or_none(v))
for (k, v) in match.groupdict().items())
else:
self.path_args = [_unquote_or_none(s)
for s in match.groups()]
return def execute(self):
self.handler = self.handler_class(self.application, self.request, **self.handler_kwargs) #获取我们自定义的RequestHandler类实例,传递参数 if self.stream_request_body: #先创建一个future 对象
self.handler._prepared_future = Future() self.handler._execute(transforms, *self.path_args, **self.path_kwargs) #执行我们自定义的,继承RequestHandler类的 _execute 函数, 所以最后我们的写的get post方法,还是在自己的那个类的_execute方法中调用执行的 return self.handler._prepared_future #返回自定义的RequestHandler future 对象

Tornado 高并发源码分析之三--- Application 对象的更多相关文章

  1. Tornado 高并发源码分析之五--- IOLoop 对象

    IOLoop主要工作 1.将TCPServer 注册到 IOLoop 的事件记到 _handlers 字段,同时注册 READ 和 ERROR 事件到 epoll 2.IOLoop 启动一个大循环,负 ...

  2. Tornado 高并发源码分析之四--- HTTPServer 与 TCPServer 对象

    主要工作: 服务器启动的时候做的事: 1.把包含了各种配置信息的 application 对象封装到了 HttpServer 对象的 request_callback 字段中,等待被调用 2.TCPS ...

  3. Tornado 高并发源码分析之一---启动一个web服务

    前言: 启动一个tornado 服务器基本代码 class HomeHandler(tornado.web.RequestHandler): #创建 RequesHandler 对象,处理接收到的 h ...

  4. Tornado 高并发源码分析之二---Tornado启动和请求处理流程

    Tornado 服务器启动流程 因为Tornado 里使用了很多传类的方式,也就是delegate,之所以要这么做,其实和 iOS 开发那样,也很多的 delegate, 如此来实现高度解耦,但是比较 ...

  5. Tornado 高并发源码分析之六---异步编程的几种实现方式

    方式一:通过线程池或者进程池 导入库futures是python3自带的库,如果是python2,需要pip安装future这个库 备注:进程池和线程池写法相同 from concurrent.fut ...

  6. ViewGroup事件分发源码分析

    1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...

  7. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  8. Flask框架 (四)—— 请求上下文源码分析、g对象、第三方插件(flask_session、flask_script、wtforms)、信号

    Flask框架 (四)—— 请求上下文源码分析.g对象.第三方插件(flask_session.flask_script.wtforms).信号 目录 请求上下文源码分析.g对象.第三方插件(flas ...

  9. JVM源码分析之Java对象头实现

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Java对象头实现 HotSpot虚拟机中,对象在内存中的布局分为三 ...

随机推荐

  1. 【.Net】Socket小示例

    引言 项目中用到了Socket,这里做个控制台小示例记录一下. Client 客户端的Receive用了异步方法,保持长连接,可以随时发送消息和响应服务端的消息,如下 static string Cl ...

  2. react-redux: counter

    store: import {createStore,applyMiddleware, compose} from "redux"; import thunk from " ...

  3. Android Framework 简介

    Android Framework 简介 简介 之前的研究太偏向应用层功能实现了,很多原理不了解没有详记,结果被很多公司技术人员鄙视了,为了减少自己的短板,重新复习了一遍C++.java.Androi ...

  4. [转载]Python注册表信息丢失的解决方案

    今天安装Python的模块时,安装失败,提示信息:Python version 2.7 required, which was not found in the registry. 原因在于Pytho ...

  5. MAC版画图软件 paintbrush 推荐,类似 windows 上系统自带的画图软件

    不想开photoshop这么重的软件,但是对于屏幕截图有需要有一点处理.这时候我想起 windows上画图的好了. 搜索了一下,知道了 paintbrush 这个软件,于是下载试用了一下,果然很好. ...

  6. stringstream 用法

    stringstream stringstream 是 C++ 提供的另一个字串型的串流(stream)物件,和之前学过的 iostream.fstream 有类似的操作方式.要使用 stringst ...

  7. Java发展前景与职业方向解析

    大多数人选择Java可能只是因为听说Java前景好.Java比较好找工作.Java语言在TIOBE排行榜上一直位于前三等等之类的原因,但是Java具体好在哪里,心里却是没有什么概念的.本文为你解答学J ...

  8. (六)java数据类型

      数据类型:决定了变量占据多大的空间,决定了变量存储什么类型的数据 整形: byte     1个字节 short    2个字节 int        4个字节 long     8个字节 浮点型 ...

  9. 【解题报告】[动态规划]-PID69 / 过河卒

    原题地址:http://www.rqnoj.cn/problem/69 解题思路: 用DP[i][j]表示到达(i,j)点的路径数,则 DP[0][0]=1 DP[i][j]=DP[i-1][j]+D ...

  10. 编写实现字符串拷贝函数strcpy()完整版

    有个题目编程实现字符串拷贝函数strcpy(),很多人往往很快就写出下面这个代码. void strcpy( char *strDest,char *strSrc ) { while(( *strDe ...