class ExtensionMiddleware是Extension Service的WSGI Application class,它的类图如下图所示。
![](https://i-blog.csdnimg.cn/blog_migrate/a6c75d15618a1772dacc05960c0235e9.png)
一个符合WSGI Application规范的class,最重要的一点是实现回调函数__call__.从这个类图中,可以看到,class ExtensionMiddleware重载了它的父类的__call__函数,所以它的父类基本没什么作用。class ExtensionMiddleware的__call__函数代码如下:
class ExtensionMiddleware(base.ConfigurableMiddleware):
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
#这里的application就是前文说的class APIRouter的实例对象
req.environ['extended.app'] = self.application
#跟Core Service一样,返回一个RouteMiddleware对象
return self._router
而self._router是在class ExtensionMiddleware的 __init__函数构建的:
class ExtensionMiddleware(base.ConfigurableMiddleware):
def __init__(self, application,
ext_mgr=None):
#这句代码与Core Service一模一样
self._router = routes.middleware.RoutesMiddleware(self._dispatch,mapper)
RoutesMiddleware最终会调用ExtensionMiddleware的_dispatch,代码如下:
def _dispatch(req):
match = req.environ['wsgiorg.routing_args'][1]
#重点在这里,如果没找到,则return req.environ['extended.app']
# req.environ['extended.app']就是Core Service的WSGI Application,就是class APIRouter的实例对象
if not match:
return req.environ['extended.app']
app = match['controller']
return app
可以看到,这个函数与class Router(class APIRouter的父类)的_dispatch相比,除了if not match:那两行,基本一模一样。正是这两行,说明了以下两个问题:
1 Core Service与Extension Service,不是并列的Service,而是嵌套关系,如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/29316b02546a7e3c804b59693b65ceab.png)
2 app_ext是app_v2.0的外层filter,也就是说,一个Request得首先到达app_ext,app_ext经过相应的处理,才会交由app_v2.0,这个相应的处理就是if not match:那两行的作用。
因此,Extension Service处理HTTP Request的基本流程,如果不考虑“跳转”这个分支,那形式上与Core Service是一样的,流程图如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a74f57b4f4d6b78d40912f57ca2b6cfa.png)