zoukankan      html  css  js  c++  java
  • EJB 工作原理

    前两天在这个版块的精华区里翻到了Robbin关于EJB的调用原理的分析,受益非浅,但感觉用纯文字来表达效果似乎不够直观,而且对RMI的阐述也略嫌少了些。这里我根据自己的一点体会,在Robbin帖子的基础上再来说说这个话题,供大家参考。 

    首先,我想先说说RMI的工作原理,因为EJB毕竟是基于RMI的嘛。废话就不多讲了,RMI的本质就是实现在不同JVM之间的调用,工作原理图如下: 

     

    它的实现方法就是在两个JVM中各开一个Stub和Skeleton,二者通过socket通信来实现参数和返回值的传递。 

    有关RMI的例子代码网上可以找到不少,但绝大部分都是通过extend the interface java.rmi.Remote实现,已经封装的很完善了,不免使人有雾里看花的感觉。下面的例子是我在《Enterprise JavaBeans》里看到的,虽然很粗糙,但很直观,利于很快了解它的工作原理。 

    1. 定义一个Person的接口,其中有两个business method, getAge() 和getName() 

    Java代码  收藏代码
    1. public interface Person {  
    2.     public int getAge(); throws Throwable;  
    3.     public String getName(); throws Throwable;  
    4. }  


    2. Person的实现PersonServer类 
    Java代码  收藏代码
    1. public class PersonServer implements Person {  
    2.     int age;  
    3.     String name;  
    4.   
    5.     public PersonServer(String name, int age); {  
    6.         this.age = age;  
    7.         this.name = name;  
    8.     }  
    9.   
    10.     public int getAge(); {  
    11.         return age;  
    12.     }  
    13.   
    14.     public String getName(); {  
    15.         return name;  
    16.     }  
    17. }  


    3. 好,我们现在要在Client机器上调用getAge()和getName()这两个business method,那么就得编写相应的Stub(Client端)和Skeleton(Server端)程序。这是Stub的实现: 
    Java代码  收藏代码
    1. import java.io.ObjectOutputStream;  
    2. import java.io.ObjectInputStream;  
    3. import java.net.Socket;  
    4.   
    5. public class Person_Stub implements Person {  
    6.     Socket socket;  
    7.   
    8.     public Person_Stub(); throws Throwable {  
    9.         // connect to skeleton  
    10.         socket = new Socket("computer_name"9000);;  
    11.     }  
    12.   
    13.     public int getAge(); throws Throwable {  
    14.         // pass method name to skeleton  
    15.         ObjectOutputStream outStream =  
    16.             new ObjectOutputStream(socket.getOutputStream(););;  
    17.         outStream.writeObject("age");;  
    18.         outStream.flush();;  
    19.   
    20.         ObjectInputStream inStream =  
    21.             new ObjectInputStream(socket.getInputStream(););;  
    22.         return inStream.readInt();;  
    23.     }  
    24.   
    25.     public String getName(); throws Throwable {  
    26.         // pass method name to skeleton  
    27.         ObjectOutputStream outStream =  
    28.             new ObjectOutputStream(socket.getOutputStream(););;  
    29.         outStream.writeObject("name");;  
    30.         outStream.flush();;  
    31.   
    32.         ObjectInputStream inStream =  
    33.             new ObjectInputStream(socket.getInputStream(););;  
    34.         return (String);inStream.readObject();;  
    35.     }  
    36. }  


    注意,Person_Stub和PersonServer一样,都implements Person。它们都实现了getAge()和getName()两个business method,不同的是PersonServer是真的实现,Person_Stub是建立socket连接,并向Skeleton发请求,然后通过Skeleton调用PersonServer的方法,最后接收返回的结果。 

    4. Skeleton实现 
    Java代码  收藏代码
    1. import java.io.ObjectOutputStream;  
    2. import java.io.ObjectInputStream;  
    3. import java.net.Socket;  
    4. import java.net.ServerSocket;  
    5.   
    6. public class Person_Skeleton extends Thread {  
    7.     PersonServer myServer;  
    8.   
    9.     public Person_Skeleton(PersonServer server); {  
    10.         // get reference of object server  
    11.         this.myServer = server;  
    12.     }  
    13.   
    14.     public void run(); {  
    15.         try {  
    16.             // new socket at port 9000  
    17.             ServerSocket serverSocket = new ServerSocket(9000);;  
    18.             // accept stub's request  
    19.             Socket socket = serverSocket.accept();;  
    20.   
    21.             while (socket != null); {  
    22.                 // get stub's request  
    23.                 ObjectInputStream inStream =  
    24.                     new ObjectInputStream(socket.getInputStream(););;  
    25.                 String method = (String);inStream.readObject();;  
    26.   
    27.                 // check method name  
    28.                 if (method.equals("age");); {  
    29.                     // execute object server's business method  
    30.                     int age = myServer.getAge();;  
    31.                     ObjectOutputStream outStream =  
    32.                         new ObjectOutputStream(socket.getOutputStream(););;  
    33.   
    34.                     // return result to stub  
    35.                     outStream.writeInt(age);;  
    36.                     outStream.flush();;  
    37.                 }  
    38.   
    39.                 if(method.equals("name");); {  
    40.                     // execute object server's business method  
    41.                     String name = myServer.getName();;  
    42.                     ObjectOutputStream outStream =  
    43.                         new ObjectOutputStream(socket.getOutputStream(););;  
    44.   
    45.                     // return result to stub  
    46.                     outStream.writeObject(name);;  
    47.                     outStream.flush();;  
    48.                 }  
    49.             }  
    50.         } catch(Throwable t); {  
    51.             t.printStackTrace();;  
    52.             System.exit(0);;  
    53.         }  
    54.     }  
    55.   
    56.     public static void main(String args []); {  
    57.         // new object server  
    58.         PersonServer person = new PersonServer("Richard"34);;  
    59.   
    60.         Person_Skeleton skel = new Person_Skeleton(person);;  
    61.         skel.start();;  
    62.     }  
    63. }  


    Skeleton类 extends from Thread,它长驻在后台运行,随时接收client发过来的request。并根据发送过来的key去调用相应的business method。 

    5. 最后一个,Client的实现 
    Java代码  收藏代码
    1. public class PersonClient {  
    2.     public static void main(String [] args); {  
    3.         try {  
    4.             Person person = new Person_Stub();;  
    5.             int age = person.getAge();;  
    6.             String name = person.getName();;  
    7.             System.out.println(name + " is " + age + " years old");;  
    8.         } catch(Throwable t); {  
    9.             t.printStackTrace();;  
    10.         }  
    11.     }  
    12. }  


    Client的本质是,它要知道Person接口的定义,并实例一个Person_Stub,通过Stub来调用business method,至于Stub怎么去和Server沟通,Client就不用管了。 

    注意它的写法: 
    Person person = new Person_Stub(); 
    而不是 
    Person_Stub person = new Person_Stub(); 

    为什么?因为要面向接口编程嘛,呵呵。 

    本文转自:http://www.iteye.com/topic/3832

  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959980.html
Copyright © 2011-2022 走看看