標籤:是什麼 int ext ejb stat 預設 mic tee .sh
Java RMI 指的是遠程方法調用 (Remote Method Invocation)。它是一種機制,可以讓在某個 JAVA 虛擬機器上的對象調用還有一個 JAVA 虛擬機器中的對象上的方法。可以用此方法調用的不論什麼對象必須實現該遠程介面。
Java RMI不是什麼新技術(在Java1.1的時代都有了),但卻是是很重要的底層技術。
大名鼎鼎的EJB都是建立在RMI基礎之上的,如今另一些開源的遠程調用組件,其底層技術也是RMI。
在大力鼓吹Web Service、SOA的時代,是不是每一個應用都應該選用笨拙的Web Service組件來實現,通過對照測試後,RMI是最簡單的,在一些小的應用中是最合適的。
以下通過一個簡單的範例來說明RMI的原理和應用,以下這個範例是一個簡單HelloWorld。但已涵蓋RMI的核心應用與開發模式。
server上的JAVA類例如以下:
遠程介面:HelloService.java
import java.rmi.Remote;import java.rmi.RemoteException;/** * 遠程介面 * @author www.wjrong.com * */public interface HelloService extends Remote {public String showMessage(String s) throws RemoteException;}
遠程介面實作類別:HelloServiceImpl .java
import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;/** * 遠程介面實作類別 * @author www.wjrong.com * */public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { private static final long serialVersionUID = 1L; public HelloServiceImpl() throws RemoteException { super(); } public String showMessage(String s) throws RemoteException { System.out.println("There is a customer call this method!"); return "Hello "+s;}}
遠程server端啟動類:SimpleServer .java
import java.rmi.Remote;import java.rmi.RemoteException;/** * 遠程介面 * @author www.wjrong.com * */public interface HelloService extends Remote {<span style="white-space:pre"></span>public String showMessage(String s) throws RemoteException;}
下面是client執行的Java類:
遠程介面:HelloService.java
import java.rmi.Remote;import java.rmi.RemoteException;/** * 遠程介面 * @author www.wjrong.com * */public interface HelloService extends Remote {public String showMessage(String s) throws RemoteException;}
client啟動類:SimpleClient .java
import java.rmi.RemoteException;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;/** * client啟動類 * @author www.wjrong.com * */public class SimpleClient {public static final int rmiPort=8080;public static void main(String[] args) {try {Context context=new InitialContext();HelloService helloService1=(HelloService)context.lookup("rmi://192.168.1.180:"+rmiPort+"/HelloService");HelloService helloService2=(HelloService)context.lookup("rmi://localhost:"+rmiPort+"/HelloService"); try { System.out.println(helloService1.showMessage("World!")); //System.out.println(helloService1==helloService2);//一個遠程對象的2個代理對象即client的2個存根地址不一樣 //System.out.println(helloService1.equals(helloService2));//一個遠程對象的2個代理對象即client的2個存根內容一樣。都是指的一樣的遠程對象} catch (RemoteException e) {e.printStackTrace();}} catch (NamingException e) {e.printStackTrace();}}}
測試時,先啟動SimpleServer,然後啟動SimpleClient
server端輸出:
There is a customer call this method!
client輸出:
Hello World!
簡單RMI測試成功!
細節須要注意的地方:
1.安全管理器
當沒有寫策略檔案覆蓋C:\Program Files\Java\jre1.6.0_05\lib\security裡的java.policy時,調用
if(System.getSecurityManager()==null)
System.setSecurityManager(new RMISecurityManager());
系統會拋出異常 java.security.AccessControlException。
原因:每一個Java應用都能夠有自己的安全管理器,它是防範惡意攻擊的主要安全衛士。
安全管理器通過執行執行階段檢查和訪問授權。以實施應用所需的安全性原則。從而保護資源免受惡意操作的攻擊。實際上,安全管理器依據Java安全性原則檔案決定將哪組許可權授予類。
然而。當不可信的類和第三方應用使用JVM 時,Java安全管理器將使用與JVM相關的安全性原則來識別惡意操作。在非常多情況下,威脅模型不包括執行於JVM中的惡意代碼。此時Java安全管理器便沒必要的。
當安全管理器檢測到違反安全性原則的操作時,JVM將引發 AccessControlException或SecurityException。
在Java應用中,安全管理器是由System類中的方法setSecurityManager設定的。
要獲得當前的安全管理器。能夠用法 getSecurityManager。 java.lang.SecurityManager類包括了非常多checkXXXX方法。如用於推斷對檔案訪問許可權的checkRead(String file)方法。
這些檢查方法調用SecurityManager.checkPermission方法。後者依據安全性原則檔案推斷調用應用是否有運行所請求的操作許可權。假設沒有,將引發SecurityException。 假設想讓應用使用安全管理器和安全性原則,可在啟動JVM時設定-Djava.security.manager選項。還能夠同一時候指定安全性原則檔案。假設在應用中啟用了Java安全管理器。卻沒有指定安全性原則檔案,那麼Java安全管理器將使用預設的安全性原則,它們是由位於檔案夾$JAVA_HOME/jre /lib/security中的java.policy定義的。
類裝載器用Policy對象協助它們決定。把一段代碼匯入虛擬機器時應該給它們什麼樣的許可權. 不論什麼時候,每個應用程式都僅僅有一個Policy對象.
2.有關rmic的疑惑rmic是為client和server端產生相關的存根和骨架(實際上就是一種代理類)。可是我們直接在javac java的過程就能夠直接調用遠程方法。好像沒有rmic的調用。
原因:在jdk5.0曾經的版本號碼中。須要用rmic命令來為遠程對象產生靜態代理類(包含存根和骨架類),而在jdk5.0中rmi架構會在執行的過程中自己主動為遠程 對象產生動態代理類(包含存根和骨架類)。從而更徹底的封裝了rmi架構的實現細節。簡化了rmi架構的使用方式。
3.registry本地注冊表
為何不啟動rmiregistry.exe就能完畢本地。注冊捏?實際上LocateRegistry.createRegistry(rmiPort)就是建立對遠程或者本地注冊表的本地引用。建立並匯出Registry執行個體。
Java RMI之HelloWorld程式以及相關的安全管理器的知識