`
biocy
  • 浏览: 34824 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

58同城开源web框架 Argo (六)

阅读更多

58同城开源的轻量级web框架 https://github.com/58code/Argo

 

随着公司规模的不断扩大,项目越来越多了,单个项目投入的人也多了起来,每个程序员都有自己的一套编码风格。身为一个处女座程序员,深深感觉到无法忍受一团乱麻似的工程。于是就需要一套强有力的规范,而且规范最好能够分级,最低层的规范最为严格,导致大家写出的代码都能差不多,也就减少人员交叉过渡的成本,越靠近业务顶层的规范就越松散、又根据业务相互隔离、可插拔,这样一来,即使无法维护,重写的成本也会降低。

一个自己定义的web框架所要完成的任务恰好包括了从低到高的全部过程,如果您的公司已经完成了服务化架构,那么web也就剩下从中高层到顶层的过程。Argo就是只关注解耦后的业务层web框架,服务化框架(分布式通讯中间件)是另一个开源项目,叫Gaea。

 

58开源的官方微博http://weibo.com/58code

 

 controller一个必不可少的功能:拦截器。

上一篇中我有一个地方一带而过,就是Router 的默认实现DefaultRouter

this.actions = buildActions(argo, controllerClasses, staticAction); 

 DefaultRouter的构造方法有注解@Inject,实例化是通过Guice

@Inject
    public DefaultRouter(Argo argo, @ArgoSystem Set<Class<? extends ArgoController>> controllerClasses, @StaticActionAnnotation Action staticAction) {

        this.argo = argo;

        argo.getLogger().info("initializing a %s(implements Router)", this.getClass());

        this.actions = buildActions(argo, controllerClasses, staticAction);

        argo.getLogger().info("%s(implements Router) constructed.", this.getClass());
    }

 那么这些参数是从哪来的,就是之前提到的com.bj58.argo.inject.ArgoModule,Argo的绑定关系都能在这里找到。

第一个参数Argo的提供实例为

@Provides
    @Singleton
    private Argo provideArgo() {
        return argo;
    }

 第二个参数带注解的 @ArgoSystem Set<Class<? extends ArgoController>> controllerClasses  提供实例为

 

@Provides
    @ArgoSystem
    @Singleton
    private Set<Class<? extends ArgoController>> provideControllerClasses() {
        return argo.getControllerClasses();
    }
 第三个参数带注解的 @StaticActionAnnotation Action staticAction  ,绑定在configure()方法中。顺便提一下,这个StaticFilesAction是处理静态文件的,跟tomcat中的DefaultServlet一样,只是有个指定的读取路径

 

 

bind(Action.class).annotatedWith(StaticActionAnnotation.class)
                .to(StaticFilesAction.class);
 

 

 

好了,DefaultRouter的实参来源也知道了,构造方法中buildActions方法的调用,还有一层buildActions方法调用,我们来看看这个

 

List<Action> buildActions(Set<ArgoController> controllers, Action staticAction) {
        
    	List<Action> actions = Lists.newArrayList();
        actions.add(staticAction);

        for (ArgoController controller : controllers) {
            ControllerInfo controllerInfo = new ControllerInfo(controller);
            List<ActionInfo> subActions = controllerInfo.analyze();

            for(ActionInfo newAction : subActions)
                merge(actions, MethodAction.create(newAction));

        }

        return ImmutableList.copyOf(actions);
    }
 这个段代码看出,全局变量  private final List<Action> actions;  就是具体的Action集合

 

代码详细描述了首先把静态资源action加入全局actions中,再把从controller类中解析出的ActionInfo集合合并到actions中。其中 merge(actions, MethodAction.create(newAction));  这段的MethodAction,就是方法action。

 

 

 

com.bj58.argo.internal.DefaultRouter.route(BeatContext beat)

 

@Override
    public ActionResult route(BeatContext beat) {

        RouteBag bag = RouteBag.create(beat);

        for(Action action : actions) {
            RouteResult routeResult = action.matchAndInvoke(bag);
            if (routeResult.isSuccess())
                return routeResult.getResult();
        }

        return ActionResult.NULL;
    }
 上面这段代码是处理请求过程,执行action的matchAndInvoke方法,静态文件action就是读取指定目录的文件返回,方法action需要看看

 

 

com.bj58.argo.internal.MethodAction.matchAndInvoke(RouteBag bag)

 

@Override
    public RouteResult matchAndInvoke(RouteBag bag) {

        if (!actionInfo.matchHttpMethod(bag))
            return RouteResult.unMatch();

        Map<String, String> uriTemplateVariables = Maps.newHashMap();

        boolean match = actionInfo.match(bag, uriTemplateVariables);
        if (!match)
            return RouteResult.unMatch();

        // PreIntercept
        for(PreInterceptor preInterceptor : actionInfo.getPreInterceptors()) {
            ActionResult actionResult = preInterceptor.preExecute(bag.getBeat());
            if (ActionResult.NULL != actionResult)
                return RouteResult.invoked(actionResult);
        }

        ActionResult actionResult = actionInfo.invoke(uriTemplateVariables);

        // PostIntercept
        for(PostInterceptor postInterceptor : actionInfo.getPostInterceptors()) {
            actionResult = postInterceptor.postExecute(bag.getBeat(), actionResult);
        }

        return RouteResult.invoked(actionResult);
    }
 PreInterceptor是前置拦截器,PostInterceptor是后置拦截器,ActionInfo封装时就根据注解把拦截器都加进去了,执行请求的时候再拿出来按顺序走一遍。拦截器的用法也很简单。

 

比如我们要写一个前置拦截器,首先写一个类,实现 PreInterceptor 接口
package com.mycompany.sample.interceptors;

import com.bj58.argo.ActionResult;
import com.bj58.argo.BeatContext;
import com.bj58.argo.interceptor.PreInterceptor;

public class MyInterceptor implements PreInterceptor{
	@Override
	public ActionResult preExecute(BeatContext beat) {
		System.out.println("in pre interceptor");
		return null;
	}
}
 然后写一个注解类,把前置注解指向这个拦截器
package com.mycompany.sample.anns;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.bj58.argo.interceptor.PreInterceptorAnnotation;
import com.mycompany.sample.interceptors.MyInterceptor;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@PreInterceptorAnnotation(value=MyInterceptor.class)
public @interface MyInterceptorAnnotation {

}
 这样前置拦截器就写好了。使用的时候只要在controller的类名前或者方法上标记这个@MyInterceptorAnnotation就可以了,比如针对demo中的 http://localhost/hello/argo有效,就把方法改成这样
@MyInterceptorAnnotation
@Path("argo")
public ActionResult helloArgo() {
     return writer().write("Hello, argo");
}
 
这时候打开  http://localhost/hello/argo  ,就会看到控制台上输出  “in pre interceptor”
-----------------------------------------------   分割线   ---------------------------------------
至此Argo大概的流程也就差不多了,还有一些更细节的功能,如果有必要的话可留言给我,交流讨论  :)
 
 
分享到:
评论

相关推荐

    58同城的web框架 Argo.zip

    Argo,源自58同城,是一款强大的开源Web框架,专为构建高性能、高可扩展性的Web应用而设计。基于Java语言,Argo在58同城内部广泛应用于各种Web站点,包括移动端和WAP访问,展现出了其在处理大规模并发和复杂业务场景...

    58同城开源框架

    【58同城开源框架】是58同城公司推出的一款开源技术框架,旨在为开发者提供高效、稳定、可扩展的开发工具。这个框架凝聚了58同城在互联网服务领域的技术积累,体现了其对软件工程的最佳实践,有助于提升开发效率,...

    argo.jar 开源的web框架

    Argo是开源的web框架,目前Argo支撑着58同城几乎所有的web站点,包括wap和手机端的访问等,现在wf每天处理10亿级的请求。经过长时间的运作与运行,证明Argo是一个可靠的、高效的web框架。 Argo在wf做了大量优化和...

    ArgoUML-0.26开源.exe

    ArgoUML-0.26开源.exe 推荐下载

    《58同城架构演进与优化二三事》沈剑

    - **自研系统**:开发了专门的图片存储系统,以及一套完整的开发框架(包括Web框架Argo和服务框架Gaea),大大降低了站点和服务的开发成本。 #### 四、更大流量挑战及解决方案 - **面临的新挑战**:如何应对更高的...

    ArgoUML-0.14.zip_Argo_argouml

    ArgoUML是一款开源的UML(统一建模语言)工具,主要版本为0.14,被封装在名为"ArgoUML-0.14.zip"的压缩包文件中。这个工具允许用户创建、编辑和管理UML模型,是软件开发过程中的一个重要辅助工具,尤其对于系统分析...

    Argo 水平和垂直样式管理后台模板UI框架

    代码超级干净,可以很容易地定制,很容易转化为任何类型的web应用程序,包括自定义管理面板,数据分析仪表盘,电子商务后端、CMS、CRM或任何SASS面板。 主要特色 响应布局(台式电脑、平板电脑、移动设备) 用Bootstrap...

    argouml.jar.zip

    ARGO UML(ArgoUML)是一款基于Java开发的开源统一建模语言(UML)工具。UML是一种广泛用于软件系统分析和设计的标准化建模语言,它提供了图形化的表示方法,帮助开发者理解和交流软件系统的结构和行为。而argouml....

    ArgoUML 0.34 使用手册

    - 开源:ArgoUML是开源项目,这意味着任何人都可以自由地下载、使用、修改和分发该软件,这促进了社区的参与和创新。 关于手册的版权,它采用了开放出版许可证(Open Publication License, OPL),这允许用户在满足...

    ArgoUML开源的uml设计软件,可以和php集成!!

    ArgoUML是一款开源的统一建模语言(UML)设计工具,专为软件开发者提供图形化界面,以便创建和管理UML模型。这款软件的独特之处在于它支持与PHP的集成,使得Web开发者也能利用UML进行项目规划和设计。 UML是一种...

    ArgoUML最新版

    ArgoUML是一款免费且开源的统一建模语言(UML)建模工具,它允许用户创建、编辑和管理各种UML模型。该软件是由Tigris组织开发并维护的,广泛应用于软件工程领域,特别是对于那些需要进行系统设计和分析的项目。通过...

    ArgoUML工具包

    ArgoUML是一款开源的计算机辅助软件工程(CASE)工具,主要用于统一建模语言(UML)的建模。它提供了丰富的功能,让用户能够便捷地设计、创建和管理UML模型。这款轻量级的应用程序在Java平台上运行,因此具有跨平台的...

    ARGO入门手册1

    ARGO入门手册1为用户提供了一个全面了解ARGO项目和ARGO数据的指南,包括ARGO浮标的工作原理、ARGO数据的类型和获取方式、ARGO数据的应用等方面。该手册旨在帮助用户更好地理解和使用ARGO数据,从而推动全球海洋研究...

    CI/CD-ArgoCD交付管理

    ArgoCD 是一个开源项目,专门设计用于Kubernetes的持续交付。它提供了一种声明性的方式来管理K8s资源,使开发者能够将应用程序的状态与Git存储库中的定义保持一致。这使得整个部署过程变得可审计、透明且易于管理。...

    ArgoUML最新版源码

    ArgoUML 是一个开源的统一建模语言(UML)建模工具,专为软件开发者和设计师提供便捷的UML模型创建环境。该工具支持多种编程语言的代码自动生成,包括C++、C、Java、PHP、SQL和C#等,极大地提升了开发效率和代码一致...

    zooviewer:像 node-zk-web 一样用 java.jsut 编写的 zookeeper web ui

    zooviewer zookeeper web ui written in java.jsut like node-zk-web 这是一个查看zookeeper节点并可以...1,基于58开源的web框架Argo,全应用无一个配置文件。详见. 2,页业端用了jquery-tree ,方便查看zk的树状节点.

    argoUML(中文版)

    argouml一款很好的开源uml工具 中文版的

    ArgoUML mac 工具

    ArgoUML是一款开源的、基于Java编写的统一建模语言(UML)设计工具,适用于多种操作系统,包括Mac OS X。它提供了全面的UML支持,使得软件开发者和系统分析师可以方便地创建、编辑和管理各种UML模型。在Mac平台上,...

    ArgoUML UML绘图工具

    **ArgoUML** 是一个基于Java开发的开源UML(统一建模语言)绘图工具,它允许用户在各种操作系统上创建、编辑和管理UML模型。由于其跨平台特性,无论是在Windows、Linux还是Mac OS X系统上,用户都能方便地使用Argo...

    Python-Argo是一个开源原生容器工作流引擎用于在Kubernetes上开发和运行应用程序

    Argo是一个开源原生容器工作流引擎用于在Kubernetes上开发和运行应用程序

Global site tag (gtag.js) - Google Analytics