黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

hessian簡介

系統(tǒng) 2471 0

一. ????? ? 遠程通訊協(xié)議的基本原理

網(wǎng)絡通信需要做的就是將流從一臺計算機傳輸?shù)搅硗庖慌_計算機,基于傳輸協(xié)議和網(wǎng)絡 ? IO ? 來實現(xiàn),其中傳輸協(xié)議比較出名的有 ? http ? ? tcp ? ? udp ? 等等, ? http ? ? tcp ? ? udp ? 都是在基于 ? Socket ? 概念上為某類應用場景而擴展出的傳輸協(xié)議,網(wǎng)絡 ? IO ? ,主要有 ? bio ? ? nio ? ? aio ? 三種方式,所有的分布式應用通訊都基于這個原理而實現(xiàn),只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協(xié)議。

二. ????? ? 應用級協(xié)議 ? Binary-RPC

Binary-RPC ? 是一種和 ? RMI ? 類似的遠程調用的協(xié)議,它和 ? RMI ? 的不同之處在于它以標準的二進制格式來定義請求的信息 ? ( ? 請求的對象、方法、參數(shù)等 ? ) ? ,這樣的好處是什么呢,就是在跨語言通訊的時候也可以使用。

來看下 ? Binary -RPC ? 協(xié)議的一次遠程通信過程:

?

1 ? 、客戶端發(fā)起請求,按照 ? Binary -RPC ? 協(xié)議將請求信息進行填充;

2 ? 、填充完畢后將二進制格式文件轉化為流,通過傳輸協(xié)議進行傳輸;

3 ? 、接收到在接收到流后轉換為二進制格式文件,按照 ? Binary -RPC ? 協(xié)議獲取請求的信息并進行處理;

4 ? 、處理完畢后將結果按照 ? Binary -RPC ? 協(xié)議寫入二進制格式文件中并返回。

???????? ? 問題總結:

1 ? 、傳輸?shù)臉藴矢袷绞牵?

??? ? 標準格式的二進制文件。

2 ? 、怎么樣將請求轉化為傳輸?shù)牧鳎?

??? ? 將二進制格式文件轉化為流。

3 ? 、怎么接收和處理流?

??? ? 通過監(jiān)聽的端口獲取到請求的流,轉化為二進制文件,根據(jù)協(xié)議獲取請求的信息,進行處理并將結果寫入 ? XML ? 中返回。

4 ? 、傳輸協(xié)議是?

Http ?

三. ????? ? Hessian ? ——一種實現(xiàn)遠程通訊的 ? library

Hessian ? 是由 ? caucho ? 提供的一個基于 ? binary-RPC ? 實現(xiàn)的遠程通訊 ? library ?

1 ? 、是基于什么協(xié)議實現(xiàn)的?

基于 ? Binary-RPC ? 協(xié)議實現(xiàn)。

2 ? 、怎么發(fā)起請求?

需通過 ? Hessian ? 本身提供的 ? API ? 來發(fā)起請求。

3 ? 、怎么將請求轉化為符合協(xié)議的格式的?

Hessian ? 通過其自定義的串行化機制將請求信息進行序列化,產(chǎn)生二進制流。

4 ? 、使用什么傳輸協(xié)議傳輸?

Hessian ? 基于 ? Http ? 協(xié)議進行傳輸。

5 ? 、響應端基于什么機制來接收請求?

響應端根據(jù) ? Hessian ? 提供的 ? API ? 來接收請求。

6 ? 、怎么將流還原為傳輸格式的?

Hessian ? 根據(jù)其私有的串行化機制來將請求信息進行反序列化,傳遞給使用者時已是相應的請求信息對象了。

7 ? 、處理完畢后怎么回應?

??? ? ???????? ? 處理完畢后直接返回, ? hessian ? 將結果對象進行序列化,傳輸至調用端。

?

????????? Hessian機制

?

hessian簡介

? 那么 Hessian 就是把 Java 對象轉變成 ? 字節(jié)序列,然后通過 Http 傳輸?shù)? ? 目標服務器上(主機 2 ),主機 2 收到這個字節(jié)序列后,按照一定的協(xié)議標準進行反序列,提交給對應的服務處理。處理完成以后以同樣的方式返回數(shù)據(jù)。

?

現(xiàn)在我們回頭看看例子中的配置( WEB-INF.XML :

配置的 Servlet ? com.caucho.hessian.server.HessianServlet

對應的參數(shù):接口 (home-api) com.alisoft.enet.hessian.Hello

???????????????????????????? 實現(xiàn) (home-class): com.alisoft.enet.hessian.HelloImpl

?

?

?

HessianServlet? 中的實現(xiàn)代碼如下(略過部分代碼):

?

HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;

InputStream is = request.getInputStream();
OutputStream os = response.getOutputStream();

//輸入流
Hessian2Input in = new Hessian2Input(is);
SerializerFactory serializerFactory = getSerializerFactory();
in.setSerializerFactory(serializerFactory);

//輸出流
AbstractHessianOutput out;
int major = in.read();
int minor = in.read();
out = new Hessian2Output(os);

out.setSerializerFactory(serializerFactory);

_homeSkeleton.invoke(in, out);

?

整個執(zhí)行步驟如下:

l ?? 接收輸入流,并通過 SerializerFactory 轉化為 ?Hessian? 特有的 ? Hessian2Input

l ?? 設置輸出流,并通過 SerializerFactory 轉化為 ?Hessian? 特有的 ? Hessian2Output

l ?? 根據(jù)配置的接口和實現(xiàn)參數(shù),調用服務,并把結果寫入到輸出流 ? Hessian2Output

l ??? Out.close()

?

Hessian 遠程訪問基于序列化和反序列化的方式。當程序運行時,程序所創(chuàng)建的各種對象都位于內存中,當程序運行結束,這些對象就結束了生命周期。對象的序列化主要有兩種用途:

l ?? 把對象的字節(jié)序列永久地保存到硬盤上,通常是放在一個文件中。

l ?? 在網(wǎng)絡上傳輸對象的字節(jié)序列

?

?

四. ????? ? Hessian ? 源碼分析

? hessian ? ? spring dm server ? 整合環(huán)境為例。

1. ???? ? 客戶端發(fā)起請求

Hessian ? 的這個遠程過程調用,完全使用動態(tài)代理來實現(xiàn)的。有客戶端可以看出。

除去 ? spring ? 對其的封裝,客戶端主要是通過 ? HessianProxyFactory ? ? create ? 方法就是創(chuàng)建接口的代理類,該類實現(xiàn)了接口, ? JDK ? ? proxy ? 類會自動用 ? InvocationHandler ? 的實現(xiàn)類(該類在 ? Hessian ? 中表現(xiàn)為 ? HessianProxy ? )的 ? invoke ? 方法體來填充所生成代理類的方法體。

客戶端系統(tǒng)啟動時:

???????? ? 根據(jù) ? serviceUrl ? ? serviceInterface ? 創(chuàng)建代理。

???????? ? HessianProxyFactoryBean ?

????????

HessianClientInterceptor ?

? ? ?????? ? ???????? ? createHessianProxy(HessianProxyFactory proxyFactory)

?

HessianProxyFactory ?

???????? ? ???????? ? public Object create(Class api, String urlName)

?

客戶端調用 ? hessian ? 服務時:

?????????????????? ? HessianProxy ? 類的 ? invoke(Object proxy, Method method, Object []args) ? 方法

??????????????????????????? ? String methodName = method.getName();// ? 取得方法名

??????????????????????????? ? Object value = args[0]; // ? 取得傳入?yún)?shù)

??????????????????????????? ? conn = ? sendRequest(mangleName, args) ? ; ????? ? // ? 通過該方法和服務器端取得連接

?

???????? ? ?????????????????? ? httpConn = (HttpURLConnection) conn;

??????????????????????????? ? code = httpConn.getResponseCode(); ??? ? // ? 發(fā)出請求

?

// ? 等待服務器端返回相應…………

?

???????? ? ?????????????????? ? is = conn.getInputStream();

??????????????????????????? ? Object value = in.readObject(method.getReturnType()); // ? 取得返回值

?

HessianProxy ? 類的 ? URLConnection sendRequest(String methodName, Object []args) ? 方法:

??? ? ???????? ? ???????? ? URLConnection ? ? conn = _factory.openConnection(_url); ????? ? // ? 創(chuàng)建 ? URLConnection ?

???????? ? ?????????????????? ? OutputStream os = conn.getOutputStream();

?

???????? ? ?????????????????? ? AbstractHessianOutput out = _factory.getHessianOutput(os); // ? 封裝為 ? hessian ? 自己的輸入輸出 ? API

???????? ? ?????????????????? ? out.call(methodName, args);

???????? ? ?????????????????? ? return conn;

????????

?

2. ???? ? 服務器端接收請求并處理請求

服務器端截獲相應請求交給:

org.springframework.remoting.caucho.HessianServiceExporter

具體處理步驟如下:

a) ?????? ? HessianServiceExporter ?

(HessianExporter) ? invoke(request.getInputStream(), response.getOutputStream());

?

b) ?????? ? HessianExporter ?

(Hessian2SkeletonInvoker) ? this.skeletonInvoker.invoke(inputStream, outputStream);

c) ?????? ? Hessian2SkeletonInvoker ?

將輸入輸出封轉化為轉化為 ? Hessian ? 特有的 ? Hessian2Input ? ? Hessian2Output

????? ? Hessian2Input in = new Hessian2Input(isToUse);

????? ? in.setSerializerFactory(this.serializerFactory);

?

????? ? AbstractHessianOutput out = null;

????? ? int major = in.read();

????? ? int minor = in.read();

????? ? out = new Hessian2Output(osToUse);

????? ? out = new HessianOutput(osToUse);

????? ? out.setSerializerFactory(this.serializerFactory);

????? ? (HessianSkeleton) this.skeleton.invoke(in, out);

?

d) ?????? ? HessianSkeleton ?

?????????? ? 讀取方法名

???????? ? String methodName = in.readMethod();

??? ? Method method = getMethod(methodName);

?

?????????? ? 讀取方法參數(shù)

???????? ? Class []args = method.getParameterTypes();

??? ? Object []values = new Object[args.length];

?

?????????? ? 執(zhí)行相應方法并取得結果

???????? ? result = method.invoke(service, values);

?

?????????? ? 結果寫入到輸出流

???????? ? out.writeObject(result);

????????

總結: ? 由上面源碼分析可知,客戶端發(fā)起請求和服務器端接收處理請求都是通過 ? hessian ? 自己的 ? API ? 。輸入輸出流都要封裝為 ? hessian ? 自己的 ? Hessian2Input ? ? Hessian2Output ? ,接下來一節(jié)我們將去了解 ? hessian ? 自己封裝的輸入輸出到底做了些什么!

五. ????? ? Hessian ? 的序列化和反序列化實現(xiàn)

hessian ? 源碼中 ? com.caucho.hessian.io ? 這個包是 ? hessian ? 實現(xiàn)序列化與反序列化的核心包。其中 AbstractSerializerFactory ? ? AbstractHessianOutput ? ? AbstractSerializer ? ? AbstractHessianInput ? AbstractDeserializer ? ? hessian ? 實現(xiàn)序列化和反序列化的核心結構代碼。

?

1. ???????? ? AbstractSerializerFactory ? ,它有 ? 2 ? 個抽象方法:

根據(jù)類來決定用哪種序列化工具類

abstract public Serializer getSerializer(Class cl) ? ? throws HessianProtocolException; ?

根據(jù)類來決定用哪種反序列化工具類

abstract public Deserializer getDeserializer(Class cl) ? ? throws HessianProtocolException;

2. ???????? ? SerializerFactory ? 繼承 ? AbstractSerializerFactory ?

? SerializerFactory ? 有很多靜態(tài) ? map ? 用來存放類與序列化和反序列化工具類的映射,這樣如果已經(jīng)用過的序列化工具就可以直接拿出來用,不必再重新實例化工具類。

? SerializerFactory ? 中,實現(xiàn)了抽象類的 ? getSerializer ? 方法,根據(jù)不同的需要被序列化的類來獲得不同的序列化工具,一共有 ? 17 ? 種序列化工具, ? hessian ? 為不同的類型的 ? java ? 對象實現(xiàn)了不同的序列化工具,默認的序列化工具是 ? JavaSerializer ?

? SerializerFactory ? 中,也實現(xiàn)了抽象類的 ? getDeserializer ? 方法,根據(jù)不同的需要被反序列化的類來獲得不同的反序列化工具,默認的反序列化工具類是 ? JavaDeserializer ?

3. ???????? ? HessianOutput ? 繼承 ? AbstractHessianOutput ? 成為序列化輸出流的一種實現(xiàn)。

它會實現(xiàn)很多方法,用來做流輸出。

需要注意的是方法,它會先調用 ? serializerFactory ? 根據(jù)類來獲得 ? serializer ? 序列化工具類

public void writeObject(Object object)

throws IOException ?

{ ?

if (object == null) { ?

writeNull(); ?

return; ?

} ?

?

Serializer serializer; ?

?

serializer = ? _serializerFactory.getSerializer(object.getClass()); ? ?

?

serializer.writeObject(object, this); ?

} ?

4. ???????? ? 現(xiàn)在我們來看看 ? AbstractSerializer ?

? writeObject ? 是必須在子類實現(xiàn)的方法, ? AbstractSerializer ? ? 17 ? 種子類實現(xiàn), ? hessian ? 根據(jù)不同的 java ? 對象類型來實現(xiàn)了不同的序列化工具類,其中默認的是 ? JavaSerializer ?

? JavaSerializer ? ? writeObject ? 方法的實現(xiàn),遍歷 ? java ? 對象的數(shù)據(jù)成員,根據(jù)數(shù)據(jù)成員的類型來獲得各自的 ? FieldSerializer ? ,一共有 ? 6 ? 中默認的 ? FieldSerializer ?

拿默認的 ? FieldSerializer ? 舉例,還是調用 ? AbstractHessianOutput ? 的子類來 ? writeObject ? ,這個時候,肯定能找到相應的 ? Serializer ? 來做序列化

?

同理可以反推出 ? hessian ? 的反序列化機制。 ? SerializerFactory ? 可以根據(jù)需要被反序列化的類來獲得反序列化工具類來做反序列化操作。

?

總結:得益于 ? hessian ? 序列號和反序列化的實現(xiàn)機制, ? hessian ? 序列化的速度很快,而且序列化后的字節(jié)數(shù)也較其他技術少。

hessian簡介


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論