2008年4月10日

          1.       書目

          精通RMI——Java與EJB企業級應用開發

          Java™ RemoteMethodInvocation Specification

          Java tutorial- RMI

          2.       基礎知識

          2.1 網絡通信協議

          網絡通信層是分布式計算環境中使用客戶/服務器結構的一個核心技術,而網絡編程中大體有兩種通信模式,無連接和面向連接的協議。

                       UDP

          UDP (universal datagram protocol)是一種用于無連接通信的標準化協議,其建立在IP協議之上,而IP協議是internet使用的基本數據傳輸協議。UDP協議的主要作用是將網絡數據流量壓縮成數據報文的形式。一個典型的數據報文就是一個二進制數據的傳輸單位。每一個數據報的前8個字節用來包含報頭信息,剩余字節則用來包含具體的傳輸數據。UDP協議并不提供數據傳送的保證機制。如果在從發送方到接收方的傳遞過程中出現數據報的丟失,協議本身并不能做出任何檢測或提示。因此,通常人們把UDP協議稱為不可靠的傳輸協議。一般用來傳輸少量數據,它資源消耗小,處理速度快。

           TCP

          TCP(transport control protocol)傳輸控制協議,標準化的面向連接的通信協議。在使用TCP協議中發送者和接收者必須在通信之前建立連接,連接建立之后被看成是一個數據流,發送者將數據發到該數據流上,接收者從該數據流上讀取數據。如果接收者也同時是發送者則連接是雙向的。通信完成后任何一方都可以關閉連接,之后的讀寫操作都會失敗。TCP協議提供了可靠的面向對象的數據流傳輸服務的規則和約定。簡單的說在TCP模式中,對方發一個數據包給你,你要發一個確認數據包給對方。Java提供的類庫都將TCP/IP協議的使用借助套接字(Socket)進行了抽象。套接字包含了建立與遠程主機的連接,與主機進行通信以及關閉連接所需要的所有操作,而這些操作實際上還是由TCP/IP來執行的。

          編組

          在應用復雜尤其是面向對象的時候,一方面會遇到處理數據或者對象的結構的問題。另一方面還會遇到面向流的用來發送字節或字符塊的網絡連接問題。此時需要將對象轉換成連接可以處理的格式,從而使自定義的對象可以通過連接管道。

          編組(marshalling)是一個將負責對象轉換成字節流的過程,然后在使用反過程----反編組將字節流轉換成對象。Java中編組的實現方式是序列化(serialization)。


              代理

          代理是一個實現給定接口的對象,但是不直接執行一些代碼計算結果,而是代表其他一些對象執行實際計算的對象。


              
              代理可以代表其他的庫或者某種類似的可以代替它執行網絡通信的東西。這就是RMI工作的原理,代理在RMI也即存根(Stub)。

          引用位于服務器中的對象的代理是如何構造的?客戶端不能有一個真的Java引用,因為Java引用只在對象位于同一個JVM時才能正常工作。構造的基本思想是為服務器對象分配一個唯一的標識序號,該序號由代理保存,此外還有對象所在的主機名。



              客戶如何請求代理

          在獲取代理時我們需要一個間接層把所有細節抽象,通過使用名字去獲得對應對象的思想就是命名。命名的一個主要作用是通過使用對象的名字,簡化獲得對象的任務。

          對于RMI來說,最通用的命名實現時RMI注冊,它具有bind和lookup操作,對于命名服務來說,客戶端其實存在一個它的代理。

          命名使用示例圖

          posted @ 2009-05-19 21:37 遲來的兵 閱讀(468) | 評論 (0)編輯 收藏

          一.String對象的比較,+操作和intern方法
          這里從一個問題入手來看看。

          package testPackage;
             public class Test {
                  
          public static void main(String[] args) {
                      String hello 
          = "Hello", lo = "lo";
                      System.out.print((hello 
          == "Hello"+ " ");
                      System.out.print((Other.hello 
          == hello) + " ");
                      System.out.print((other.Other.hello 
          == hello) + " ");
                      System.out.print((hello 
          == ("Hel" + "lo")) + " ");
                      System.out.print((hello 
          == ("Hel" + lo)) + " ");
                      System.out.println(hello 
          == ("Hel" + lo).intern());
                  }

              }
              class Other {
                  
          static String hello = "Hello";
              }


          package other;
              public class Other {
                  
          static String hello = "Hello";
              }

          正確答案:true true true true false true
          主要要點有:
          1.所有內容相同的String指向同一個內存塊。但String對象不能是通過new操作創建出來。主要原因是JVM對String做了優化,String加載之后會持有一個常量池,
          只要在常量池中找到內容相同的String就會把其引用返回。而new操作是直接在內存中分配新空間。



          2.Java中有兩種綁定,靜態和動態。如果+操作的兩邊是常量表達式那么會在采用靜態綁定,也就是說編譯之后值已經定下來了。而如果有一邊是通過new操作創建出
          來的那么會采用動態綁定,只有在運行的時候才知道其具體的值。
          3.String的intern方法會到常量池里面找是否有相同內容的String,如果有則返回其引用。如果沒有則把這個String對象添加到常量池之中并放回其引用。額外說
          下,intern在英文中有保留區的意思,這樣好理解其作用。intern方法還是native的。
          二.String中的正則表達式使用

          String中有些方法是需要正則表達式作為參數的。這個時候就要主要不要傳錯參數。最典型的例子就是replaceAll(String regex, String replacement)。第一個
          參數是需要正則表達式的,而第二參數是普通的字符串。
                  String ss = "???";
                  ss 
          = ss.replaceAll("?""=");//運行到這里會拋出PatternSyntaxException,因為“?”在正則表達式里面是特殊符號,需要轉義。
                  ss = ss.replaceAll("[?]""=");//正確,我個人比較傾向于這種寫法。
                  ss = ss.replaceAll("\\?""=");//正確,對“?”做轉義。

          因此在使用split,replaceAll,replaceFirst等方法時要特別注意是不是需要轉義.

          posted @ 2008-12-06 19:39 遲來的兵 閱讀(239) | 評論 (0)編輯 收藏

          1.優先使用primitive type
          2.不要使用Boolean作為返回值。
          3.在初始化所有變量之后再創建類的實例。
          4. 用URI代替URL,使用URI的create方法代替new。
          5. 注意使用inputsream的skip方法,此方法會返回實際跳過的長度,最好自己監聽返回值。
          6. ?:運算符會返回最大范圍的類型,如:true?new Intege(2): new Float(1.0);將會返回2.0.
          7. 盡量使用double,而不是float。

          posted @ 2008-04-21 19:24 遲來的兵 閱讀(228) | 評論 (0)編輯 收藏

          1. interface來定義系統對外提供的服務,有抽象類來做擴展。盡量用interface作為參數類型。

          2. ThreadLocal類,定義了一個變量的本地副本,與原有變量隔離,作用類似static變量,只是不共享。可用set添加變量,get去獲取變量。變量類型不限制。

          3. Eclipse plug in開發中可以實現IRuntimeClasspathProvider接口。可以提供用launch configuration去獲得unresolvedresolved classpath。開發人員可以在resolveClasspath方法中加入自定義的classpath。實現類需要注冊在extension point中。

                /**

                 *Computesandreturnsanunresolvedclasspathforthegivenlaunchconfiguration.

                 *Variableandcontainerentriesarenotresolved.

                 *

                 *@paramconfigurationlaunchconfiguration

                 *@returnunresolvedpath

                 *@exceptionCoreExceptionifunabletocomputeapath

                 */

                public IRuntimeClasspathEntry[] computeUnresolvedClasspath(ILaunchConfiguration configuration) throws CoreException;

               

                /**

                 *Returnstheresolvedpathcorrespondingtothegivenpath,inthecontextofthe

                 *givenlaunchconfiguration.Variableandcontainerentriesareresolved.Thereturned

                 *(resolved)pathneednothavethesamenumberofentriesasthegiven(unresolved)

                 *path.

                 *

                 *@paramentriesentriestoresolve

                 *@paramconfigurationlaunchconfigurationcontexttoresolvein

                 *@returnresolvedpath

                 *@exceptionCoreExceptionifunabletoresolveapath

                 */

                public IRuntimeClasspathEntry[] resolveClasspath(IRuntimeClasspathEntry[] entries, ILaunchConfiguration configuration) throws CoreException;

          A provider extension is defined in plugin.xml. Following is an example definition of a runtime classpath provider extension.

           <extension point="org.eclipse.jdt.launching.classpathProviders">
             <classpathProvider 
                id="com.example.ExampleClasspathProvider"
                class="com.example.ExampleClasspathProviderImpl"
             </classpathProvider>
           </extension>

          4. plug in 開發中可以用JavaRuntime 去得到運行環境的信息。        
          IRuntimeClasspathProvider provider = JavaRuntime
          .getClasspathProvider(configuration);

          其中configurationILaunchConfiguration類型的。

          4. Eclipse plug in開發中獲取文件。兩種解決辦法:1.plug in實例中讀取文件的URL,然后用FileLocator把這個URL轉化成文件路徑;2.直接利用FileLocatorfind方法。

          方法1

                      //filepath 是需要定位的文件

                      String filepath = "/bin/resources/test.jar";

                      //instance 是當前plug in的實例

                      URL url = instance.getBundle().getEntry(filepath);

                      String path = null;

                      try {

                            path = FileLocator.resolve(url).getPath();

                      } catch (IOException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                      }

                      returnnew Path(path);

                }

          方法2

                      String filepath = "/bin/resources/test.jar";

                      URL url = FileLocator.find(instance.getBundle(),new Path(filepath),null);

                      try {

                            path = FileLocator.resolve(url).getPath();

                      } catch (IOException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                      }

          5. 可以利用JarOutputStream來寫jar包。必須為JarOutputStream 實例創建至少一個Entry,可以調用putNextEntry方法。

                      Manifest mf = new Manifest();

                      JarOutputStream jar = new JarOutputStream(new FileOutputStream("MainTest.jar")mf);

                      Properties properties = new Properties();

                      jar.putNextEntry(new ZipEntry("MainTest.property"));

                      properties.store(jar, "this is a test");

                      jar.close();

          6. 得到IJavaModle

                IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace()

                                        .getRoot());

                IJavaProject[] projects = model.getJavaProjects();

                IPackageFragmentRoot[] roots = projects[i]                                          .getPackageFragmentRoots();

           然后可以依次得到對應elements

          posted @ 2008-04-10 17:12 遲來的兵 閱讀(561) | 評論 (0)編輯 收藏


          posts - 6, comments - 8, trackbacks - 0, articles - 1

          Copyright © 遲來的兵

          主站蜘蛛池模板: 英德市| 林口县| 诏安县| 原平市| 阜宁县| 冀州市| 青神县| 古丈县| 轮台县| 德昌县| 西宁市| 鄂伦春自治旗| 白朗县| 恭城| 藁城市| 莆田市| 桃源县| 随州市| 九龙县| 察雅县| 乐都县| 莫力| 吴桥县| 霍林郭勒市| 长治县| 志丹县| 宁明县| 阿拉善左旗| 山西省| 大关县| 永吉县| 航空| 吴川市| 基隆市| 即墨市| 共和县| 顺义区| 大庆市| 宜阳县| 于田县| 博客|