【原创】功能强大的一款struts2插件“struts2-concurrent-plugin”

struts2-concurrent-plugin

简介



struts2-bigpipe-plugin是struts2的一款插件,插件功能是把一个页面分成很多个模块。每个模块执行业务代码并渲染有三种模式:

  • 串行模式
  • 服务器端并行模式
  • bigpipe模式



下面具体介绍一下每个模式


1.串行模式是每个模块顺序执行



2.服务器端并行模式是每个模块并行执行(多线程),当所有的模块执行完之后拼成一个完整的html后再响应给客户端浏览器。



3.bigpipe模式是facebook发明的一种浏览器-服务器之间的并发模式。跟服务器端并行模式一样,bigpipe模式也是模块并行执行,不同的是,bigpipe模式在每个模块执行完之后,马上给客户端浏览器响应。好处在于客户端能够立刻看到响应,提升用户体验。这个过程让我们不经想到Ajax,跟ajax区别在于bigpipe只有一个连接,一方面能够节约服务器连接资源,另一方面节省tcp连接的时间。

使用文档



1.增加插件pom依赖,或者手动导入插件包
2.编写普通的struts2 Action组件

在插件的模型里面,action组件不再是执行业务逻辑代码的地方,理论上只用于为每个子模块创建参数上下文。具体执行业务逻辑由Pipe组件完成。


    @View(ftlPath = "/index.ftl", type = ExecuteType.BIGPIPE)
public class IndexAction extends ActionSupport {

    @Param
    String name;
    @Autowired
    @Param
    public User user;

    @Override
    public String execute() throws Exception {
    //do prepare pipe execute context at here
        return "pipe";
    }

    

@View 注释是插件里面的一个重要注释,在Action组件里面@View的功能有两个:
1.指定对应的页面的整体freemarker文件路径 2.指定此页面的模块的执行方式,枚举类型ExecuteType.SYNC、ExecuteType.CONCURRENT、ExecuteType.BIGPIPE分别对应上一节介绍的三种模式.模式切换只有这里需要改动,其他地方无需任何改动.

@Param 指定的属性表示此参数会被此页面模块使用的到,也就是说会被注入到模块里相应的属性里。

其他地方和普通的struts2 action没有任何区别。


3.编写模块组件

示例


@View(ftlPath = "demo/one.ftl", weight = Weight.HEIGHT, key = "pipeone")
public class PipeOne implements Pipe {
    @Param
    private String name;
    @Getter
    @Autowired
    private User user;
    @Getter
    private int age;
    @Getter
    private int time;
    @Override
    public void execute() {
        //do business logic at here
    }
}

示例说明

Pipe组件对应页面的一个模块,Pipe组件需要实现Pipe接口。Pipe接口定义只有一个execute()方法。

@View 注释有三个功能

  • 指定freemarker文件地址
  • 指定在页面级freemarker中引用模块的key,默认是ftl文件名(不包括后缀)。例如上面示例中的模块key为one
  • 指定此模块的权重。这里解释一下权重的概念:一个页面可能某些模块具有高权重,比如base info信息在整个页面必须首先渲染出来,而有些模块得在页面其他部分都渲染完之后在渲染也就是优先级是最低的。插件实现了三种优先级Weight.HEIGHT、Weight.NORMALL、Weight.LOW,默认是Normal。每个级别里面的模块之间没有优先级关系。Weight.HEIGHT模块可以确保在其他两个级别之前渲染。申明一点这里指的渲染是以用户视觉看到的来说。

@Param 会自动被注入的参数,参数值来源就是action中定义的带@Param参数。示例中@Getter是lombok插件的一个功能,一个参数被注释为@Getter,在编译的时候自动补全参数的getter()方法。模块中的含有getter方法和param注释的属性,都可以在ftl文件中引用。换句话说@getter参数是模块的输出,对应的@Param参数是模块的输入。

另外考虑到在模块中使用到HttpServletRequest、HttpServletResponse、ServletContext、获取cookie值等是很常用的需求。插件考虑到这一点提供了PipeSupport类,模块pipe通过继承pipeSupport可以很方便的获得这些功能的支持,类似于ActionSupport。

4.struts.xml配置

示例:

<struts>
<constant name="struts.objectFactory"
          value="org.apache.struts2.spring.StrutsSpringObjectFactory"/>
<constant name="struts.concurrent.plugin.downgrade"
          value="MyPipeDowngrading"/>
<constant name="struts.devMode" value="true"/>
<package name="default" extends="struts-default" namespace="/">
    <result-types>
        <result-type name="bigpipe" class="org.le.view.BigPipeResult">
        </result-type>
    </result-types>
    <action name="hello" class="action.IndexAction">
        <result name="success" type="freemarker">/index.ftl</result>
        <result name="pipe" type="bigpipe">Pipes.PipeOne,Pipes.PipeTwo,
            Pipes.PipeThree,Pipes.PipeFour
        </result>
    </action>
</package>
</struts>

在中定义了一种新的resultType类型为bigpipe,然后在Action result定义中使用。示例中 Pipes.PipeOne,Pipes.PipeTwo, Pipes.PipeThree,Pipes.PipeFour result中定义了四个pipe,pipe的值为Pipe的全名。

5. action对应的ftl

struts2-bigpipe-plugin

${name}

${one}
${two}
${three}
${four}

结语



此插件功能强大,使用起来十分方便,而且能够大幅度提高性能、用户体验,特别是bigpipe模式。并且对于页面开发可以起到页面代码解耦的功能。市面上有很多后端模块并行执行的框架,但大部分都是在struts层之下做的,多一层就多了很多的复杂度。我个人觉得这些功能应该在MVC层做的,也就是struts负责的。读者看完上面的教程之后,应该也会发现用一个struts插件实现这些功能是多么自然的事情。

插件还有很多不完善的地方,特别是bigpipe js部分。由于本人对前端知识不是特别了解,所以这部分还有很多改善的空间。也借此希望如果有兴趣的TX,一块开发完善此项目。

附github:https://github.com/lepdou/struts2-concurrent-plugin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值