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

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

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

    ALL is Well!

    敏捷是一條很長的路,摸索著前進(jìn)著

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      30 隨筆 :: 23 文章 :: 71 評(píng)論 :: 0 Trackbacks

    本文為原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處BlogJava

    在上一篇 Hessian構(gòu)建分布式系統(tǒng)應(yīng)用 的基礎(chǔ)上,我們對(duì)程序進(jìn)行改進(jìn)。
    現(xiàn)在有以下比較突出的問題:
    a.如果hessian服務(wù)端我要做的業(yè)務(wù)很多,怎么辦?
    我要定義很多個(gè)接口,然后再寫實(shí)現(xiàn)類,最煩的是還要配置它。
    我的設(shè)想是,hessian服務(wù)只提供一個(gè)歸口,再此對(duì)外的接口實(shí)現(xiàn)中反射調(diào)用具體的業(yè)務(wù)類。

    b.客戶端在調(diào)用時(shí),每次調(diào)用遠(yuǎn)程接口都要用以下代碼嗎:

    String url = "http://localhost:8080/HessianService/remote/service";
    HessianProxyFactory factory 
    = new HessianProxyFactory();
    ServiceRemote rmt 
    = (ServiceRemote) factory.create(ServiceRemote.class, url);


    顯然是不需要的。
    我們可以通過加入緩存的方式對(duì)其進(jìn)行改良,我們也可以通過Spring在客戶端管理它。

    一、完善hessian服務(wù)端實(shí)現(xiàn):
    1.首先修改ServiceRemote接口:

    package com.al;

    import java.util.Map;

    @SuppressWarnings(
    "unchecked")
    public interface ServiceRemote  {
        
    public Map callService(String target, Map inputMap) throws Exception;
    }

    callService為統(tǒng)一入口,在此做如下約定:
    1)target字符串為要調(diào)用的service的完整類路徑+要調(diào)用的方法。
    2)service的方法均用以下方法簽名:
    public Map ***(Map inputMap);
    入?yún)镸ap,返回值也為Map,基本可以滿足所有情況了。(至少入?yún)镸ap,很適合調(diào)用iBatis來對(duì)DB進(jìn)行操作。)

    2.修改接口實(shí)現(xiàn)類Service,此類不做具體業(yè)務(wù),而是反射調(diào)用具體業(yè)務(wù)類:

    package com.al;

    import java.lang.reflect.Method;
    import java.util.Map;

    import org.apache.commons.beanutils.MethodUtils;
    import org.apache.commons.lang.StringUtils;

    @SuppressWarnings(
    "unchecked")
    public class Service implements ServiceRemote {

        
    public Map callService(String target, Map inputMap) throws Exception {
            String className 
    = StringUtils.substringBeforeLast(target, ".");
            String methodName 
    = StringUtils.substringAfterLast(target, ".");
            Class serviceClass 
    = loadClass(className);
            Method method 
    = getMethod(serviceClass, methodName, Map.class);
            
    // 提供訪問效率
            method.setAccessible(true);
     
    // 調(diào)用具體業(yè)務(wù)類
            return (Map) method.invoke(serviceClass.newInstance(), inputMap);
        }

        
        
    private static <T> Class<T> loadClass(String className) throws ClassNotFoundException {
                
    return (Class<T>) getClassLoader().loadClass(className);
        }

        
        
    private static ClassLoader getClassLoader() {
            
    return Thread.currentThread().getContextClassLoader();
        }

        
        
    private static Method getMethod(Class<?> cls, String name, Class<?> parameterTypes) {
            
    return MethodUtils.getAccessibleMethod(cls, name, parameterTypes);
        }

    }

     

    3.舉個(gè)例子,服務(wù)端提供業(yè)務(wù)類DisplayUserService.java

    package com.al.service;

    import java.util.HashMap;
    import java.util.Map;

    @SuppressWarnings(
    "unchecked")
    public class DisplayUserService {
        
    public static final String selectUsers = "com.al.service.DisplayUserService.selectUsers";
        
    public static final String deleteUser = "com.al.service.DisplayUserService.deleteUser";
        
        
    public Map selectUsers(Map inputMap) {
            Map ret 
    = new HashMap();
            
    // 數(shù)據(jù)庫操作取得用戶列表 省略
            ret.put("User""User");
            
    return ret;
        }

        
        
    public Map deleteUser(Map inputMap) {
            
    // 數(shù)據(jù)庫操作取得用戶列表 省略
            return null;
        }

    }


    所有其他配置不變,請(qǐng)參考上一篇 Hessian構(gòu)建分布式系統(tǒng)應(yīng)用 。


    二、客戶端代碼的修改:
    1.加入spring進(jìn)行管理:
    application.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
        
    <bean id="serviceRemote" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
            
    <property name="serviceUrl" value="http://localhost:8080/HessianService/remote/service" />
            
    <property name="serviceInterface" value="com.al.ServiceRemote" />
        
    </bean>
    </beans>

     

    2.客戶端如下調(diào)用即可:

    package com.ai.client;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.al.ServiceRemote;
    import com.al.service.DisplayUserService;

    public class ClientTest {
        
    public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext cxt 
    = new ClassPathXmlApplicationContext("application.xml");
            ServiceRemote rmt 
    = (ServiceRemote)cxt.getBean("serviceRemote");
            System.out.println(rmt.callService(DisplayUserService.selectUsers, 
    null));
        }

    }


    另外一種方法是自己實(shí)現(xiàn)緩存。
    也就是第一次調(diào)用遠(yuǎn)程代碼時(shí)生成ServiceRemote對(duì)象,將其保存在靜態(tài)的容器(HashMap)中,
    每次準(zhǔn)備調(diào)用此遠(yuǎn)程代碼時(shí),先判斷容器中是否有ServiceRemote對(duì)象,有則直接將其取出并使用即可,要注意的就是在這個(gè)容器上的同步問題。
    具體實(shí)現(xiàn)就不做了,很簡單。

    在項(xiàng)目中,對(duì)于客戶端代碼來講,還是有許多工作要做的:
    1) 如果我們要調(diào)用多個(gè)遠(yuǎn)程服務(wù)怎么辦?
    我們要提供一個(gè)統(tǒng)一調(diào)用,將遠(yuǎn)程調(diào)用的動(dòng)作封裝起來,讓使用的人不知道自己調(diào)用了不同的遠(yuǎn)程服務(wù)。
    只要調(diào)用某個(gè)方法、傳入?yún)?shù)即可。

    2) 如何方便開發(fā)員調(diào)試遠(yuǎn)程的服務(wù)代碼?
    在做分布式系統(tǒng)開發(fā)的時(shí)候,如果每修改一下應(yīng)用層的service,就要對(duì)其進(jìn)行發(fā)布,然后再去調(diào)用看是否已OK,那效率會(huì)很低。

    3) 如何管理多方調(diào)用的遠(yuǎn)程服務(wù)?

    4) 如何提高遠(yuǎn)程調(diào)用的效率?
    是否可以通過對(duì) 對(duì)象進(jìn)行緩存、方法是否也可以緩存?甚至是對(duì)調(diào)用結(jié)果進(jìn)行緩存?

    5) 等等..
    這些在具體的項(xiàng)目中都是不得不考慮的問題。以后再慢慢討論吧。

    posted on 2010-10-17 22:10 李 明 閱讀(1704) 評(píng)論(1)  編輯  收藏 所屬分類: J2EESpring

    評(píng)論

    # re: Hessian構(gòu)建分布式系統(tǒng)應(yīng)用[續(xù)][未登錄] 2012-08-11 15:07 哈哈
    目前我正考慮類似的方式構(gòu)建一個(gè)系統(tǒng)出現(xiàn)了一下問題:
    1.如你所說,如果只采用一個(gè)暴露接口,當(dāng)訪問量比較大時(shí)是不是有性能問題呢?
    2.服務(wù)端的業(yè)務(wù)異常信息如何返回給客戶端?比如,當(dāng)Insert一條數(shù)據(jù),ID重復(fù),目前我是返回一個(gè)錯(cuò)誤碼給客戶端,客戶端根據(jù)錯(cuò)誤碼得到相應(yīng)信息


    希望多多交流  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 亚洲综合校园春色| 欧洲精品成人免费视频在线观看| 99久久国产精品免费一区二区 | 亚洲乱码中文字幕综合| gogo免费在线观看| 中文字幕亚洲码在线| 亚洲精品美女在线观看播放| 日韩视频在线精品视频免费观看| 亚洲一区二区三区丝袜| 亚洲综合区图片小说区| 黑人精品videos亚洲人| 亚洲精品国产综合久久一线| 啦啦啦手机完整免费高清观看| 131美女爱做免费毛片| 免费国产99久久久香蕉| 国产一级高青免费| 国产伦精品一区二区免费| 免费播放美女一级毛片| 亚洲av日韩综合一区久热| 亚洲AV无码第一区二区三区 | 色窝窝亚洲AV网在线观看| 波多野结衣亚洲一级| 亚洲六月丁香六月婷婷色伊人| 亚洲尹人九九大色香蕉网站| 亚洲AV综合色区无码另类小说| 国产亚洲av人片在线观看| 免费在线视频你懂的| 一级做a免费视频观看网站| 国产精品亚洲二区在线| 精品国产_亚洲人成在线| 无码亚洲成a人在线观看| 亚洲欧美在线x视频| 18禁亚洲深夜福利人口| 激情小说亚洲图片| 日日摸夜夜添夜夜免费视频| 污视频网站在线观看免费| 男女猛烈激情xx00免费视频| 一区二区免费国产在线观看| 久青草视频97国内免费影视| 伊人免费在线观看高清版| 日本视频免费高清一本18|