深入详解美团点评CAT跨语言服务监控(九)CAT管理平台MVC框架

本文深入解析美团点评的CAT管理平台的MVC框架,介绍了其初始化过程、请求生命周期管理和模块路由机制。CAT的MVC框架在处理请求时,通过RequestLifecycle和ModelManager协调ModuleModel与Handler,实现页面请求的处理和控制权转移。通过对请求URL的解析和路由,找到对应的页面处理器执行相应操作。
摘要由CSDN通过智能技术生成

上一篇:CAT跨语言服务链监控(八)报表持久化

    在第2章我们讲到,服务器在初始化CatServlet 之后, 会初始化 MVC,MVC也是继承自AbstractContainerServlet , 同样也是一个 Servlet 容器,这是一个非常古老的MVC框架,当时Spring MVC 还并不成熟,但是所有MVC框架的核心思想都是一致的。

 

   

 

    在初始化完CatServlet之后,我们就会调用 MVC 的父类 AbstractContainerServlet 去初始化MVC容器,初始化最核心的步骤是调用MVC子类的initComponents(...) 函数去创建请求周期管理器(RequestLifecycle),并将容器上下文(ServletContext)的指针传递给 RequestLifecycle。容器类RequestLifecycle 的配置信息位于文件 web-framework-4.0.0.jar/META-INF/plexus/components-web-framework.xml 中。

 

public class MVC extends AbstractContainerServlet {
    protected void initComponents(ServletConfig config) throws Exception {
        if(this.m_handler == null) {
            String contextPath = config.getServletContext().getContextPath();
            String path = contextPath != null && contextPath.length() != 0?contextPath:"/";
            this.getLogger().info("MVC is starting at " + path);
            this.initializeCat(config);
            this.initializeModules(config);
            this.m_handler = (RequestLifecycle)this.lookup(RequestLifecycle.class, "mvc");
            this.m_handler.setServletContext(config.getServletContext());
            config.getServletContext().setAttribute("mvc-servlet", this);
            this.getLogger().info("MVC started at " + path);
        }
    }
}

    从上面类图, 我们看到MVC 拥有DefaultRequestLifecycle的一个实例,用于完成每次请求的生命周期内的所有工作,例如URL的解析,路由的实现,异常处理等等。DefaultRequestLifecycle 拥有3个重要的成员变量,m_servletContext 用于维护servlet容器的上下文,m_builder用于创建请求上下文,它是管理请求解析、路由的核心,m_actionHandlerManager 对象用于管理负责页面请求的动作执行器,他会被plexus容器实例化。

下面我展示下业务页面相关的类,如下,然后分析下 MVC 的核心逻辑。

接下来我们先来具体看看 RequestContextBuilder 对象的功能以及初始化的逻辑,如下类图。

     RequestContextBuilder 利用 ModelManager 来管理模块(Module)与动作模型(Model), 模块与动作模型是请求上下文中2个非常重要的概念,不要搞混淆,模块是大的页面分类,目前整个CAT页面平台只有2个模块,分别是报表模块(ReportModule)和系统模块(SystemModule),动作模型则是两大模块下面具体的页面路由信息,他维护具体页面处理器(Handler)的指针、以及处理的函数,以便在请求到来的时候,根据URL找到相应页面处理器,将控制权交给页面处理器(Handler),由页面处理器进行页面逻辑处理,比如获取报表数据、登录、配置修改、页面展示等等,Module对象的指针和动作模型的信息都会存在于ModuleModel对象中,ModuleModel相当于MVC框架的路由转发控制核心,而Handler相当于MVC中的Controller层。接下来我们详细剖析。

      ModelManager 的 ModuleRegistry 对象负责对模块的实例化。ModuleRegistry类实现了Initializable方法,所以在plexus实例化ModuleRegistry之后,遍会调用他的initialize()方法实例化ReportModule和SystemModule对象了,如下:

public class ModuleRegistry extends ContainerHolder implements Initializable {
   private String m_defaultModuleName;
   private Module m_defaultModule;
   private List<Module> m_modules;
   
	 @Override
   public void initialize() throws InitializationException {
      if (m_defaultModuleName != null) {
         m_defaultModule = lookup(Module.class, m_defaultModuleName);
      }

      m_modules = lookupList(Module.class);
   }
}

我们来看两个页面URL:

存储报表页面: http://localhost:8080/cat/r/t

配置管理页面:http://localhost:8080/cat/s/config

上面URL中的 "r" 代表的就是ReportModule,所有的报表相关的页面都在ReportModule中定义,"s"  则代表SystemModule,系统相关的页面都在SystemModule中定义,上面参数的"t"和"config"是路由动作(Action),后续将会详细讲解,这里的 "r"、"s" 实际上是模块名称,该参数在哪里定义的呢? 在模块(Module)的java定义文件中,我们看到模块元数据(ModuleMeta) 的定义如下:

@ModuleMeta(name = "s", defaultInboundAction = "config", defaultTransition = "default", defaultErrorAction = "default")
@ModuleMeta(name = "r", defaultInboundAction = "home", defaultTransition = "default", defaultErrorAction = "default")

     在元数据中,就有名称信息,除此之外,元数据还定义了模块的默认路由动作,报表默认动作是"home",即我们一进去看到的首页, 而系统默认动作则是"config"。在两个模块的java定义文件中,除了Module元数据的定义之外,还有对该模块下所有页面处理器(Handler)的定义:

系统页面处理器:

@ModulePagesMeta({
    com.dianping.cat.system.page.login.Handler.class,
    com.dianping.cat.system.page.config.Handler.class,
    com.dianping.cat.system.page.plugin.Handler.class,
    com.dianping.cat.system.page.router.Handler.class
})

报表页面处理器:

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值