<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent

    Vicent's blog
    隨筆 - 74, 文章 - 0, 評(píng)論 - 5, 引用 - 0
    數(shù)據(jù)加載中……

    Apache Commons Chain簡(jiǎn)明手冊(cè)

    基本對(duì)象

    1. ? Command 接口。它是 Commons Chain 中最重要的接口,表示在 Chain 中的具體某一步要執(zhí)行的命令。它只有一個(gè)方法: boolean execute(Context context) 。如果返回 true ,那么表示 Chain 的處理結(jié)束, Chain 中的其他命令不會(huì)被調(diào)用;返回 false ,則 Chain 會(huì)繼續(xù)調(diào)用下一個(gè) Command ,直到:

    - ????????? Command 返回 true

    - ????????? Command 拋出異常;

    - ????????? Chain 的末尾;

    2. ? Context 接口。它表示命令執(zhí)行的上下文,在命令間實(shí)現(xiàn)共享信息的傳遞。 Context 接口的父接口是 Map ContextBase 實(shí)現(xiàn)了 Context 。對(duì)于 web 環(huán)境,可以使用 WebContext 類及其子類( FacesWebContext PortletWebContext ServletWebContext )。

    3. ? Chain 接口。它表示“命令鏈”,要在其中執(zhí)行的命令,需要先添加到 Chain 中。 Chain 的父接口是 Command ChainBase 實(shí)現(xiàn)了它。

    4. ? Filter 接口。它的父接口是 Command ,它是一種特殊的 Command 。除了 Command execute ,它還包括一個(gè)方法: boolean postprocess(Context context, Exception exception) Commons Chain 會(huì)在執(zhí)行了 Filter execute 方法之后,執(zhí)行 postprocess (不論 Chain 以何種方式結(jié)束)。 Filter 的執(zhí)行 execute 的順序與 Filter 出現(xiàn)在 Chain 中出現(xiàn)的位置一致,但是執(zhí)行 postprocess 順序與之相反。如:如果連續(xù)定義了 filter1 filter2 ,那么 execute 的執(zhí)行順序是: filter1 -> filter2 ;而 postprocess 的執(zhí)行順序是: filter2 -> filter1

    5. ? Catalog 接口。它是邏輯命名的 Chain Command 集合。通過(guò)使用它, Command 的調(diào)用者不需要了解具體實(shí)現(xiàn) Command 的類名,只需要通過(guò)名字就可以獲取所需要的 Command 實(shí)例。

    基本使用

    1. ???????? 執(zhí)行由順序的命令組成的流程,假設(shè)這條流程包含 1 2 3 步。

    t ??????? 實(shí)現(xiàn)要執(zhí)行的命令步驟:

    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;

    ??? }

    }

    ?

    t ??????? 注冊(cè)命令,創(chuàng)建執(zhí)行的 Chain

    public class CommandChain extends ChainBase {

    ??? // 增加命令的順序也決定了執(zhí)行命令的順序

    ??? 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 。除了在程序中注冊(cè)命令之外,還可以使用配置文件來(lái)完成。

    t ??????? 對(duì)于例 1 ,配置文件可以寫成:

    <?xml version="1.0" encoding="gb2312"?>

    <catalog>

    ?????? <chain name="CommandChain">

    ??????? <!-- 定義的順序決定執(zhí)行的順序 -->

    ????????????? <command id="command1" className= "chain.Command1"/>

    ????????????? <command id="command2" className= "chain.Command2"/>

    ????????????? <command id="command3" className= "chain.Command3"/>

    ?????? </chain>

    ? ?? <command name="command4" className="chain.Command1"/>

    </catalog>

    t ??????? 裝入配置文件的代碼如下:

    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 應(yīng)用。為了在 web 應(yīng)用中加載 Catalog ,需要在對(duì)應(yīng)的 web.xml 中添加:

    <context-param>

    ? <param-name>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</param-name>

    ? <param-value>resources/catalog.xml</param-value>

    </context-param>

    <listener>

    ? <listener-class>org.apache.commons.chain.web.ChainListener</listener-class>

    </listener>

    缺省情況下, Catalog 會(huì)被加載到 Servlet Context 中,對(duì)應(yīng)的屬性名字是“ catalog ”。因此獲取 Catalog

    Catalog catalog = (Catalog) request.getSession()

    ??????? ????????????????????.getServletContext().getAttribute("catalog");

    4. ???????? Filter 的使用。 Filter 是一種特殊的 Command ,它除了 execute 方法會(huì)被執(zhí)行之外,同時(shí)還會(huì)在 Chain 執(zhí)行完畢之后(不論是正常結(jié)束還是異常結(jié)束)執(zhí)行 postprocess 。因此,可以將它和 Servlet 中的 Filter 做類比: execute 相當(dāng)于處理前操作(相對(duì)下一個(gè) Command 來(lái)說(shuō)), postprocess 相當(dāng)于處理后操作。 Filter 的使用以及配置和 Command 完全一樣,為了在 Command1 之前添加一個(gè) Filter

    t ??????? 定義 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;

    ??? }

    }

    ?

    t ??????? 修改配置文件,在上述的配置文件中的 command1 之前添加:

    <command id="filter1" className= "chain.Filter1"/>

    ?????? Filter 的還有一個(gè)常用的用法:對(duì)于異常的過(guò)濾。當(dāng) Command 拋出異常時(shí),最終中會(huì)返回到最開(kāi)始的調(diào)用處。有時(shí)期望不拋出這些異常,而在內(nèi)部消化掉,那么就可以利用 Filter 。因?yàn)?/span> Commons Chain 確保會(huì)調(diào)用已經(jīng)執(zhí)行了 execute 方法的 Filter postprocess 方法,即使在出現(xiàn)異常時(shí)也是如此。因此,對(duì)應(yīng)的 postprocess 方法可以寫為:

    ?????? public boolean postprocess(Context arg0, Exception arg1) {

    ??????? // 返回 true ,表示非空異常已被處理,無(wú)需再拋出。

    ??????? // 否則,異常會(huì)被拋出

    ??????? if( null!= arg1) return true;

    ??????? else return false;

    ??? }

    5. ???????? 對(duì)于復(fù)雜的 Chain ,可能需要使用內(nèi)嵌的 Chain ,內(nèi)嵌 Chain 可以類比一個(gè)子過(guò)程。此時(shí),可以使用 LookupCommand 。以例 1 為例,假設(shè)其中的 command2 需要擴(kuò)展成為一個(gè)子過(guò)程,那么配置文件修改如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <catalog>

    ?????? <chain name="CommandChain">

    ????????????? <command id="command1" className= "chain.Command1"/>

    ????????????? <command id="filter1" className= "chain.Filter1"/>

    ????????????? <command

    className="org.apache.commons.chain.generic.LookupCommand"

    ???????????????????? name="chain_command3"

    ???????????????????? optional="true"/>

    ????????????? <command id="command2" className= "chain.Command2"/>

    ?????? </chain>

    ?????? <chain name="chain_command3">

    ????????????? <command id="command3" className= "chain.Command3"/>

    ?????? </chain>

    </catalog>

    其中, optional 如果設(shè)為 true ,那么如果沒(méi)有找到對(duì)應(yīng)的類時(shí),程序不會(huì)拋出異常。此時(shí),仿佛命令不存在一樣。如果為 false ,那么在找不到對(duì)應(yīng)的類時(shí),會(huì)拋出異常。

    6. ???????? <define> 的使用。配置文件的引入,使得 Commons Chain 的靈活性大大的提高。在實(shí)際的使用過(guò)程中,存在著同一個(gè) Command 被多個(gè) Chain 使用的情形。如果每次都書寫 Command 的類名,尤其是前面的包名特別長(zhǎng)的情況下,是非常枯燥的。而 <define> 的作用就是為了解決這樣的麻煩。通過(guò)定義 Command Chain 的別名,來(lái)簡(jiǎn)化書寫。例 5 的配置文件,可以書寫成:

    <?xml version="1.0" encoding="gb2312"?>

    <catalog>

    ??? <!-- Command 的別名,以后直接使用即可 -->

    ?????? <define name="command1" className="chain.Command1"/>

    ?????? <define name="command2" className="chain.Command2"/>

    ?????? <define name="command3" className="chain.Command3"/>

    ?????? <define name="filter1" className="chain.Filter1"/>

    ?????? <define name="lookupCommand"

    ????????????? ??? className="org.apache.commons.chain.generic.LookupCommand"/>

    ??????

    ?????? <chain name="CommandChain">

    ????????????? <command1 id="1"/>

    ????????????? <filter1 id="2"/>

    ????????????? <lookupCommand name="chain_command3" optional="true"/>

    ????????????? <command2 id="3"/>

    ?????? </chain>

    ??????

    ?????? <chain name="chain_command3">

    ????????????? <command3 id="3"/>

    ?????? </chain>

    ??????

    ?????? <command1 name="command4"/>

    </catalog>

    ?

    總結(jié)

    ?????? Commons Chain 實(shí)現(xiàn)了 Chain of Responsebility Command 模式,其中的 Catalog + 配置文件的方式使得調(diào)用方和 Command 的實(shí)現(xiàn)方的耦合度大大的降低,提高了靈活性。對(duì)于配置文件,通常可以:

    - ????????? 作為 Command 的索引表,需要時(shí)按名字索引創(chuàng)建實(shí)例。

    - ????????? 利用 Chain 以及內(nèi)嵌 Chain ,完成一組連續(xù)任務(wù)和 Command 的復(fù)用,引入 Filter 可以獲得與 Servlet Filter 一樣的好處。

    - ????????? 使用 <define> 定義別名,簡(jiǎn)化書寫。

    posted on 2006-08-22 10:47 Binary 閱讀(2156) 評(píng)論(0)  編輯  收藏 所屬分類: Apache jakarta

    主站蜘蛛池模板: 亚洲区精品久久一区二区三区| 久久精品夜色噜噜亚洲A∨| 亚洲精品国产成人99久久| 免费看男人j放进女人j免费看| 亚洲综合国产一区二区三区 | 国产中文字幕在线免费观看| 亚洲一区二区三区在线播放| 一个人看的www免费在线视频| 免费看国产一级特黄aa大片| 免费无码AV一区二区| 亚洲最大激情中文字幕| 免费一级毛片在线播放视频| 亚洲av无码不卡一区二区三区| 亚洲a无码综合a国产av中文| 无码国产亚洲日韩国精品视频一区二区三区| 日韩欧美亚洲中文乱码| 亚洲国产高清在线一区二区三区| 亚洲18在线天美| 国产精品色午夜视频免费看| 四虎影视永久在线精品免费| 久久天天躁狠狠躁夜夜免费观看| 亚洲自国产拍揄拍| 在线观看亚洲免费| 99re6在线视频精品免费| 亚洲国产精品网站久久| 国产美女精品久久久久久久免费 | 3d成人免费动漫在线观看| 亚洲AV综合色区无码二区偷拍 | 国产日产亚洲系列| 100部毛片免费全部播放完整| 亚洲精品无码久久久久牙蜜区| 精品无码免费专区毛片| 久久亚洲精品国产精品婷婷| 亚洲国产天堂久久综合| 久久99精品视免费看| 亚洲不卡av不卡一区二区| 国产卡一卡二卡三免费入口| 麻豆安全免费网址入口| 亚洲综合久久久久久中文字幕| 女人18毛片a级毛片免费视频| 你懂的免费在线观看|