commons-chain解析(1)

在公司一个常规模块中,准备使用责任链的模式处理业务,但是不想使用Apache Camel这样很大的框架,于是乎想到了Commons-Chain这个很小很轻便的框架,所以准备花点时间研究下Commons-Chain的框架代码。

 

Commons-Chain有5个很重要接口:Catalog,Chain,Command,Context,Filter

Catalog:储存Command的地方,其目的是我们不需要知道Command的classname,只需要关注我们赋予                  Command对应的name

Chain:继承了Command接口,一条chain当中可以有很多Command,而且Chain也是一条Command,                 所以Chain可以嵌入到另外一条Chain里面使用

Command:最顶级的基本接口,定义了execute(Context context)方法,同时提供了                                                             CONTINUE_PROCESSING和PROCESSING_COMPLETE的两个静态boolean变量

Context:上下文接口,集成于Map

Filter:是一个特殊的Command,一个Command在执行的时候,如果它是实现了Filter接口的,就会调用                postprocess(Context context, Exception exception)这个方法

 

我们先解析这条接口结构,Command->Chain->ChainBase,上下文我们则采用Context->ContextBase

package com.axxis.service.atgneo;

import org.apache.commons.chain.Command;
import org.apache.commons.chain.impl.ChainBase;

import com.lanecrawford.webservice.productcatalog.bean.PRODUCT;

public class ProductCommandChain extends ChainBase {


	public ProductCommandChain() {
		addCommand(new LoadBasicData());
		addCommand(new BuildProductFromUda());
	}
	
	public static void main(String[] args) throws Exception {
		Command prosser = new ProductCommandChain();
		ProductConext context = new ProductConext();
		prosser.execute(context);
		for (PRODUCT pro : context.getPRODUCTS()) {
			System.out.println(pro);
		}
	}
	
}

这就是一个最基本的责任链的使用,一是往Chain里面addCommand,二是将这个Chain本身作为一个上层的Command调用execute方法,并传入我们的context上下文

 

首先我们看看ChainBase这个类,

173643_sAPd_2648651.png

4个构造器,一目了然;commands存放我们command的地方,frozen是一个开关,默认为false(关闭),当Command执行execute的时候,frozen被置为true,这个时候ChainBase中的addCommand无法正常执行,会抛出异常


    protected boolean frozen = false;

    public void addCommand(Command command) {

        if (command == null) {
            throw new IllegalArgumentException();
        }
        if (frozen) {
            throw new IllegalStateException();
        }
        Command[] results = new Command[commands.length + 1];
        System.arraycopy(commands, 0, results, 0, commands.length);
        results[commands.length] = command;
        commands = results;

    }

最后需要关注的是下面这段代码

        boolean handled = false;
        boolean result = false;
        for (int j = i; j >= 0; j--) {
            if (commands[j] instanceof Filter) {
                try {
                    result =
                        ((Filter) commands[j]).postprocess(context,
                                                           saveException);
                    if (result) {
                        handled = true;
                    }
                } catch (Exception e) {
                      // Silently ignore
                }
            }
        }

就是我们Command在exceute的时候按照Commad[]逆序调用postprocess方法(如果这个Command实现了Filter这个接口)。

 

ok明天接着写

 

转载于:https://my.oschina.net/pypy/blog/729670

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值