请求上下文

源码粗略分析

'''
globals:
    _request_ctx_stack = LocalStack()
    _app_ctx_stack = LocalStack()
    current_app = LocalProxy(_find_app)
    request = LocalProxy(partial(_lookup_req_object, "request"))
    session = LocalProxy(partial(_lookup_req_object, "session"))
    g = LocalProxy(partial(_lookup_app_object, "g"))

1  run_simple(host, port, self, **options),self是app,执行self(),Flask里面的__call__

2 在__call__里面执行的return self.wsgi_app(environ, start_response),把执行结果返回,
    environ请求相关的, start_response响应相关的

3 self.wsgi_app(environ, start_response)的源码:
        def wsgi_app(self, environ, start_response):  
            #得到一个RequestContext的对象,这对象里面有包含了request和session       
            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)
                
        3.1 执行 ctx = self.request_context(environ):environ请求相关的:的源码
                return RequestContext(self, environ) self是app,environ请求相关的
                3.1.1RequestContext(self, environ)实例化一个RequestContext对象
                        def __init__(self, app, environ, request=None, session=None):
                            self.app = app
                            if request is None:
                                request = app.request_class(environ)
                            self.request = request
                            self.url_adapter = None
                            try:
                                self.url_adapter = app.create_url_adapter(self.request)
                            except HTTPException as e:
                                self.request.routing_exception = e
                            self.flashes = None
                            self.session = session
            3.1总结:ctx = self.request_context(environ)以后ctx为RequestContext对象,这个对象有request,session
        
        3.2   ctx.push()里面执行了
                _request_ctx_stack.push(self):self是ctx
            3.2.1_request_ctx_stack这个是一个全局变量是LocalStack()的对象
                _request_ctx_stack.push(self)就是执行LocalStack里面的push方法
                
                3.2.1.1 LocalStack里面的push方法,obj参数是ctx
                        def push(self, obj):
                            rv = getattr(self._local, "stack", None)
                            if rv is None:
                                self._local.stack = rv = []
                            #把obj,也就是ctx存到了LOCAL对象中的storage,存的格式为: storage={"执行id":{'stack':[ctx,]}}
                            rv.append(obj)
                            return rv
                3.2.1.2 rv = getattr(self._local, "stack", None)这个self._local是LOCAL对象
                
        3.3 response = self.full_dispatch_request(),这里是响应函数与请求扩展
                def full_dispatch_request(self):
                    #第一请求的函数,before_first_request里面的所有函数
                    self.try_trigger_before_first_request_functions()
                    try:
                        #信号
                        request_started.send(self)
                        #before_request执行的结果,如果这个里面有返回值,后面的befor_request都不会执行
                        #如果 rv = self.preprocess_request(),rv为None,才会执行self.dispatch_request()
                        #也就响应函数
                        rv = self.preprocess_request()
                        if rv is None:
                            # 真正的响应函数,如果上面的before_request没有返回值就执行它,并拿到rv这个返回值
                            rv = self.dispatch_request()
                    except Exception as e:
                        rv = self.handle_user_exception(e)
                    #请求之后的函数,也就是after_request的函数
                    return self.finalize_request(rv)
            
        
        3.4 请求结束后执行ctx.auto_pop(error)把它在LOCAL对象中删除.删除的是ctx
posted @ 2020-01-05 18:09  chanyuli  阅读(147)  评论(0编辑  收藏  举报