设为首页 收藏本站
查看: 720|回复: 0

[经验分享] apache chain简明手册

[复制链接]

尚未签到

发表于 2015-8-3 09:05:56 | 显示全部楼层 |阅读模式
http://www.onjava.com/pub/a/onjava/2005/03/02/commonchains.html?page=3
基本对象
  1.   Command 接口。它是 Commons Chain 中最重要的接口,表示在 Chain 中的具体某一步要执行的命令。它只有一个方法: boolean execute(Context context) 。如果返回true ,那么表示 Chain 的处理结束, Chain 中的其他命令不会被调用;返回 false ,则 Chain 会继续调用下一个 Command ,直到:
  -           Command 返回 true ;
  -           Command 抛出异常;
  -           Chain 的末尾;
  2.   Context 接口。它表示命令执行的上下文,在命令间实现共享信息的传递。 Context接口的父接口是 Map , ContextBase 实现了 Context 。对于 web 环境,可以使用WebContext 类及其子类( FacesWebContext 、 PortletWebContext 和ServletWebContext )。
  3.   Chain 接口。它表示“命令链”,要在其中执行的命令,需要先添加到 Chain 中。Chain 的父接口是 Command , ChainBase 实现了它。
  4.   Filter 接口。它的父接口是 Command ,它是一种特殊的 Command 。除了Command 的 execute ,它还包括一个方法: boolean postprocess(Context context, Exception exception) 。 Commons Chain 会在执行了 Filter 的 execute 方法之后,执行postprocess (不论 Chain 以何种方式结束)。 Filter 的执行 execute 的顺序与 Filter出现在 Chain 中出现的位置一致,但是执行 postprocess 顺序与之相反。如:如果连续定义了 filter1 和 filter2 ,那么 execute 的执行顺序是: filter1 -> filter2 ;而postprocess 的执行顺序是: filter2 -> filter1 。
  5.   Catalog 接口。它是逻辑命名的 Chain 和 Command 集合。通过使用它, Command的调用者不需要了解具体实现 Command 的类名,只需要通过名字就可以获取所需要的 Command 实例。
基本使用
  1.          执行由顺序的命令组成的流程,假设这条流程包含 1 、 2 和 3 步。
  þ         实现要执行的命令步骤:
  public class Command1 implements Command {
      public boolean execute(Context arg0) throws Exception {
          System.out.println("Command1 is done!");
          return false;
      }
  }
  public class Command2 implements Command {
      public boolean execute(Context arg0) throws Exception {
          System.out.println("Command2 is done!");   
          return false;
      }
  }
  public class Command3 implements Command {
      public boolean execute(Context arg0) throws Exception {
          System.out.println("Command3 is done!");
          return true;
      }
  }
  
  
  
  
  þ         注册命令,创建执行的 Chain :
  public class CommandChain extends ChainBase {
      // 增加命令的顺序也决定了执行命令的顺序
      public CommandChain(){
          addCommand( new Command1());
          addCommand( new Command2());
          addCommand( new Command3());
      }
     
      public static void main(String[] args) throws Exception{
          Command process = new CommandChain();
          Context ctx= new ContextBase();
          process.execute( ctx);
      }
  }
  
  
  
  
  2.          使用配置文件加载 Command 。除了在程序中注册命令之外,还可以使用配置文件来完成。
  þ         对于例 1 ,配置文件可以写成:
  
  
        
          
                
                
                
        
       
  
  þ         装入配置文件的代码如下:
  public class CatalogLoader {
      static final String cfgFile= "/chain/chain-cfg.xml";   
      public static void main(String[] args) throws Exception{
          CatalogLoader loader= new CatalogLoader();
          ConfigParser parser= new ConfigParser();
        
          parser.parse( loader.getClass().getResource( cfgFile));
          Catalog catalog= CatalogFactoryBase.getInstance().getCatalog();
          // 加载 Chain
          Command cmd= catalog.getCommand("CommandChain");
          Context ctx= new ContextBase();
          cmd.execute( ctx);
  // 加载 Command
  cmd= catalog.getCommand( "command4");
          cmd.execute( ctx);
      }
  }
  注意:使用配置文件的话,需要使用 Commons Digester 。而 Digester 则依赖:Commons  Collections 、 Commons Logging 和 Commons BeanUtils 。
  3.          加载 Catalog 到 web 应用。为了在 web 应用中加载 Catalog ,需要在对应的web.xml 中添加:
  
    org.apache.commons.chain.CONFIG_CLASS_RESOURCE
    resources/catalog.xml
  
  
    org.apache.commons.chain.web.ChainListener
  
  缺省情况下, Catalog 会被加载到 Servlet Context 中,对应的属性名字是“ catalog”。因此获取 Catalog :
  Catalog catalog = (Catalog) request.getSession()
                              .getServletContext().getAttribute("catalog");
  4.          Filter 的使用。 Filter 是一种特殊的 Command ,它除了 execute 方法会被执行之外,同时还会在 Chain 执行完毕之后(不论是正常结束还是异常结束)执行postprocess 。因此,可以将它和 Servlet 中的 Filter 做类比: execute 相当于处理前操作(相对下一个 Command 来说), postprocess 相当于处理后操作。 Filter 的使用以及配置和 Command 完全一样,为了在 Command1 之前添加一个 Filter :
  þ         定义 Filter
  public class Filter1 implements Filter {
      public boolean postprocess(Context arg0, Exception arg1) {
          System.out.println("Filter1 is after done!");
          return false;
      }
      public boolean execute(Context arg0) throws Exception {
          System.out.println("Filter1 is done!");
          return false;
      }
  }
  
  
  
  
  þ         修改配置文件,在上述的配置文件中的 command1 之前添加:
  
         Filter 的还有一个常用的用法:对于异常的过滤。当 Command 抛出异常时,最终中会返回到最开始的调用处。有时期望不抛出这些异常,而在内部消化掉,那么就可以利用 Filter 。因为 Commons Chain 确保会调用已经执行了 execute 方法的 Filter 的postprocess 方法,即使在出现异常时也是如此。因此,对应的 postprocess 方法可以写为:
         public boolean postprocess(Context arg0, Exception arg1) {
          // 返回 true ,表示非空异常已被处理,无需再抛出。
          // 否则,异常会被抛出
          if( null!= arg1) return true;
          else return false;
      }
  5.          对于复杂的 Chain ,可能需要使用内嵌的 Chain ,内嵌 Chain 可以类比一个子过程。此时,可以使用 LookupCommand 。以例 1 为例,假设其中的 command2 需要扩展成为一个子过程,那么配置文件修改如下:
  
  
        
                
                
                
                
        
        
                
        
  
  其中, optional 如果设为 true ,那么如果没有找到对应的类时,程序不会抛出异常。此时,仿佛命令不存在一样。如果为 false ,那么在找不到对应的类时,会抛出异常。
  6.           的使用。配置文件的引入,使得 Commons Chain 的灵活性大大的提高。在实际的使用过程中,存在着同一个 Command 被多个 Chain 使用的情形。如果每次都书写 Command 的类名,尤其是前面的包名特别长的情况下,是非常枯燥的。而  的作用就是为了解决这样的麻烦。通过定义 Command 和 Chain 的别名,来简化书写。例 5 的配置文件,可以书写成:
  
  
     
        
        
        
        
        
        
        
                
                
                
                
        
        
        
                
        
        
        
  
  
  
  
  
总结
         Commons Chain 实现了 Chain of Responsebility 和 Command 模式,其中的 Catalog + 配置文件的方式使得调用方和 Command 的实现方的耦合度大大的降低,提高了灵活性。对于配置文件,通常可以:
  -           作为 Command 的索引表,需要时按名字索引创建实例。
  -           利用 Chain 以及内嵌 Chain ,完成一组连续任务和 Command 的复用,引入Filter 可以获得与 Servlet Filter 一样的好处。
  -           使用  定义别名,简化书写。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-93514-1-1.html 上篇帖子: 更改Apache默认起始(索引)页面:DirectoryIndex 下篇帖子: Windows下php5.3.8,Apache,MySQL,phpMyAdmin,zendOPtimizer,xdebug的安装及配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表