Java RMI: Java Remote Method Invocation oder Java RMI (Java Remote Method Invocation) ist eine Anwendungsprogrammierschnittstelle, die zum Implementieren von Remoteprozeduraufrufen in der Programmiersprache Java verwendet wird.
Es ermöglicht Programmen, die auf dem Client ausgeführt werden, Objekte auf dem Remote-Server aufzurufen. Mit der Remote-Methodenaufruffunktion können Java-Programmierer Vorgänge in einer Netzwerkumgebung verteilen. Der gesamte Zweck von RMI besteht darin, die Verwendung von Remote-Schnittstellenobjekten so weit wie möglich zu vereinfachen.
Wir wissen, dass Remote Procedure Call (RPC) von einem Prozess verwendet werden kann, um einen Prozess in einem anderen Prozess (wahrscheinlich auf einem anderen Remote-Host) aufzurufen und so Prozessverteilungsfunktionen bereitzustellen. Javas RMI macht auf Basis von RPC einen weiteren Schritt nach vorne und ermöglicht die Kommunikation zwischen verteilten Objekten.
RMI (Remote Method Invocation) ist ein Remote-Methodenaufruf, der es einem Objekt, das auf einer Java Virtual Machine läuft, ermöglicht, eine Methode für ein Objekt aufzurufen, das auf einer anderen Java Virtual Machine läuft.
Die beiden virtuellen Maschinen können in unterschiedlichen Prozessen auf demselben Computer oder auf verschiedenen Computern im Netzwerk ausgeführt werden.
[JavaRMI]
1. Funktionsprinzip
RMI ermöglicht es einem Java-Programm, einen anderen Computer im Netzwerk aufzurufen Methode des Java-Objekts des Computers, dann ist der Effekt des Aufrufs derselbe wie der Aufruf auf dem lokalen Computer. Laienhaft ausgedrückt: Es gibt eine Klasse auf Maschine A, und Maschine B ruft durch Fernaufrufe die Methoden in dieser Klasse auf.
RMI, Remote Method Invocation (Remote Method Invocation) ist das Rückgrat von Enterprise JavaBeans und eine bequeme Möglichkeit, verteilte Java-Anwendungen zu erstellen. RMI ist sehr einfach zu bedienen, aber sehr leistungsstark.
Die Grundlage von RMI ist die Schnittstelle. Die RMI-Architektur basiert auf einem wichtigen Prinzip: Die Definition der Schnittstelle und die Definition der spezifischen Implementierung der Schnittstelle sind getrennt. Im Folgenden verwenden wir konkrete Beispiele, um einen einfachen Remote-Computing-Dienst und ein Client-Programm zu erstellen, das ihn verwendet
2. RMI umfasst:
1. Remote-Service-Schnittstellendefinition
2. Spezifische Implementierung der Remote-Service-Schnittstelle
3. Stub- und Skeleton-Dateien
Ein Server, auf dem der Remote-Service ausgeführt wird
5 , der es Clients ermöglicht, den Remote-Dienst zu erkennen
6. Ein Anbieter von Klassendateien (ein HTTP- oder FTP-Server)
7. Einer, der dieses Remote-Service-Client-Programm erfordert
3. Was ist der Zweck von RMI?
Der Zweck von RMI besteht darin, Dienste für die Fernkommunikation zwischen verteilten Java-Anwendungen bereitzustellen und Verteilungsdienste bereitzustellen.
Derzeit sind die Hauptanwendungen in verschiedenen J2EE-Projekt-Frameworks wie Spring und EJB gekapselt (sowohl Spring als auch EJB kapseln RMI-Technologie).
RMI in Spring implementieren:
① Definieren Sie Dienstschnittstellen auf der Serverseite und definieren Sie bestimmte Klassen, um diese Schnittstellen zu implementieren
② Verwenden Sie die Klasse org.springframework.remoting.rmi.RmiServiceExporter auf der Serverseite, um Dienste zu registrieren; >③ In Der Client verwendet org.springframework.remoting.rmi.RmiProxyFactoryBean, um die Proxy-Funktion des Remote-Dienstes zu implementieren
④ Definieren Sie eine Klasse auf dem Client, um auf dieselbe Dienstschnittstelle wie der Server zuzugreifen
IV , Was sind die Einschränkungen von RMI? JRMP ist ein Protokoll, das speziell für Java-Remoteobjekte entwickelt wurde. Da JRMP speziell für Java-Objekte entwickelt wurde, bietet RMI keine ausreichende Unterstützung für Anwendungssysteme, die in Nicht-Java-Sprachen entwickelt wurden.Kann nicht mit Objekten kommunizieren, die in Nicht-Java-Sprachen geschrieben sind (was bedeutet, dass nur Remoteaufrufe von Code unterstützt werden, bei denen sowohl der Client als auch der Server Java-Programme sind).
5. Was sind die Einschränkungen von RMI?
Da sowohl der Client als auch der Server in Java geschrieben sind, ist die Voraussetzung für die Plattformkompatibilität, dass beide Parteien darauf laufen versionkompatible Java Virtual Machine.6. Parameter und Rückgabewerte von RMI-Aufrufen an Remote-Methoden
Beim Aufrufen von Methoden für Remote-Objekte kann der Client nicht nur Originaltypdaten als Parameter verwenden Darüber hinaus können Objekte entsprechend dem Rückgabewert auch als Parameter übergeben werden, die primitive Typen oder Objekte zurückgeben können. Diese werden durch die Objektserialisierungstechnologie (Serialisierung) von Java implementiert. (Mit anderen Worten: Wenn der Parameter oder Rückgabewert ein Objekt ist, muss er die serialisierbare Schnittstelle implementieren)7. Grundmodell der RMI-Anwendung
8. RMI-Architektur
Stub/Skelettschicht: clientseitiger Stub und serverseitiges Framework;
Remote-Referenzschicht: Verwaltet das Remote-Referenzverhalten
Transportschicht: Aufbau und Verwaltung von Verbindungen und Verfolgung von Remote-Objekten
9. RMI-Klassen und -Schnittstellen (Klassen, die benötigt werden). Vervollständigen Sie ein einfaches RMI).
(1) Remote-Schnittstelle: Es handelt sich um eine markierte Schnittstelle, die keine Methoden definiert
Öffentliche Schnittstelle Remote{}
in In RMI deklariert die Remote-Schnittstelle den Satz von Methoden, die von der Remote-Java-Virtual-Machine aufgerufen werden können. Die Remote-Schnittstelle erfüllt die folgenden Anforderungen:
1. Die Remote-Schnittstelle muss direkt oder indirekt die Java.rmi.Remote-Schnittstelle erweitern und als öffentlich deklariert sein, es sei denn, der Client und die Remote-Schnittstelle befinden sich im selben Paket
2. Wenn Sie eine Methode in einer Remote-Schnittstelle deklarieren, muss sie zusätzlich zum Auslösen einer Methode, die sich auf die Anwendung bezieht, auch eine RemoteException-Ausnahme (oder ihre Superklasse, IOExcepion oder Exception) enthalten
3 . In einer Remote-Methodendeklaration muss ein als Parameter oder Rückgabewert deklariertes Remote-Objekt als Remote-Schnittstelle deklariert werden, nicht als Implementierungsklasse der Schnittstelle.
(2) Die abstrakte Klasse RemoteObject implementiert die Remote-Schnittstelle und die Serializable-Schnittstelle. Sie und ihre Unterklassen stellen RMI-Serverfunktionen bereit.
(3) Die LocateRegistry final()-Klasse wird verwendet, um einen Verweis auf das Boot-Remote-Objektregistrierungsserverprogramm eines bestimmten Hosts abzurufen (d. h. einen Stub zu erstellen) oder um einen Remote-Objektregistrierungsdienst zu erstellen Programm, das Anrufe auf einem bestimmten Port empfangen kann.
Serverseite: Bereitstellung von Remote-Objektdiensten für andere Clients
SomeService servcie=……;//远程对象服务
1. Registry Registry=LocateRegisty.getRegistry(); //Registry ist eine Schnittstelle, sie erbt Remote, diese Methode gibt lokal zurück Verweis des Hosts auf die Remote-Objekt-Registrierung am Standard-Registrierungsport 1099.
2. getRegistry(int port) gibt den Verweis des lokalen Hosts auf die Remote-Objektregistrierung am angegebenen Port zurück;
3. getRegistry(String host) gibt den angegebenen Host auf dem Standard zurück Registry-Port 1099 Verweis auf die Remote-Objekt-Registrierung;
4. getRegistry(String host, int port) gibt einen Verweis auf die Remote-Objekt-Registrierung auf dem angegebenen Host und Port zurück
5. bind(“I dienen",service);//bind(String name,Remote obj) Bindet die Remote-Referenz an den in dieser Registrierung angegebenen Namen. name: der Name, der sich auf die Remote-Referenz bezieht. obj: eine Referenz auf das Remote-Objekt (normalerweise ein Stub)
6. unbind (String name) entfernt die Bindung des angegebenen Namens in der Registrierung.
7. Rebind (String-Name, Remote-Objekt), wenn der Remote-Name identisch ist, verwerfen Sie die vorhandene Bindung . lookup(String name) Gibt die Remote-Referenz zurück, die an den angegebenen Namen in der Registrierung gebunden ist, gibt Remote
9 zurück, String[] list() Gibt ein Array von Namen zurück, die in dieser Registrierung gebunden sind. Dieses Array enthält eine Momentaufnahme der Namen in dieser Registrierung, die beim Aufruf dieser Methode gebunden wurden.
Client: Stellen Sie entsprechende Serviceanfragen an den Server.
Registry Registry=LocateRegisty.getRegistry();
SomeService servcie=(SomeService)registry.lookup(“Ich serviere”);Servcie.requestService();
(4) Die Benennungsklasse ähnelt der Registry-Klasse.
Client:
Naming.lookup(String url) url 格式如下"rmi://localhost/"+远程对象引用
Server:
Registry registry=LocateRegistry.createRegistry(int port); Naming.rebind(“service”,service);
(5) RMISecurityManager-Klasse
Wenn im RMI-Referenzprogramm kein Sicherheitsmanager festgelegt ist, werden Stubs ausgeführt und Klassen können nur aus dem lokalen Klassenpfad geladen werden, wodurch sichergestellt wird, dass die Anwendung nicht durch Code gefährdet wird, der von Remote-Methodenaufrufen heruntergeladen wird
Der folgende Code muss ausgeführt werden, um RMISecurityManager zu installieren, bevor Code vom Remote-Host heruntergeladen wird:
System.setSecurityManager(new RMISecurityManager());
10. Demo-EntwicklungUm eine Demo zu schreiben, sind wir in zwei Teile unterteilt Ein Teil des serverseitigen Codes ist der clientseitige Code. Der clientseitige Code dient hauptsächlich der Verwendung des serverseitigen Codes. Natürlich ist dieser Code sehr einfach, nur um das Problem zu veranschaulichen, wird die tatsächliche Verwendung komplizierter.
(1) Unser Zweck
Erstellen Sie ein serverseitiges Java-Projekt, einschließlich des Codes auf der Remote-Seite, definieren Sie die Schnittstelle, definieren Sie die Schnittstellenimplementierung und erstellen Sie dann ein clientseitiges Java-Projekt um die Remote-Seite über RMI-Methoden in Enddiensten zu nutzen.
(2) Unsere Codestruktur
(3) Remote-Service-Code
1. Definition der Remote-Service-Schnittstelle
Der erste Schritt besteht darin, den Java-Code der Serviceschnittstelle zu erstellen und zu kompilieren. Diese Schnittstelle definiert alle Funktionen zur Bereitstellung von Remote-Diensten. Das Folgende ist das Quellprogramm:
UserManagerInterface.java
package cn.com.tt.rmiserver.stub; import java.rmi.Remote; import java.rmi.RemoteException; import cn.com.tt.rmiserver.bean.Account; public interface UserManagerInterface extends Remote{ public String getUserName() throws RemoteException; public Account getAdminAccount() throws RemoteException; }
Die Schnittstelle muss die Remote-Klasse erben und jede definierte Methode muss eine RemoteException-Ausnahme auslösen . Objekt.
2. Spezifische Implementierung der Schnittstelle
Der zweite Schritt besteht darin, die obige Schnittstelle zu implementieren:
UserManagerImp.java
package cn.com.tt.rmiserver; import java.rmi.RemoteException; import cn.com.tt.rmiserver.stub.UserManagerInterface; import cn.com.tt.rmiserver.bean.Account; public class UserManagerImp implements UserManagerInterface { public UserManagerImp() throws RemoteException { } private static final long serialVersionUID = -3111492742628447261L; public String getUserName() throws RemoteException{ return "TT"; } public Account getAdminAccount() throws RemoteException{ Account account=new Account(); account.setUsername("TT"); account.setPassword("123456"); return account; } }
3 , implementiert die serialisierbare Serialisierungsschnittstelle. Das heißt, ein serialisierbares Objekt, das zwischen Client und Server übertragen werden kann.
Account.java
package cn.com.tt.rmiserver.bean; import java.io.Serializable; public class Account implements Serializable,Cloneable{ private static final long serialVersionUID = -1858518369668584532L; private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
4. Definieren Sie den Hauptprogrammeintrag auf der Serverseite.
Entry.java
package cn.com.tt.rmiserver.entry; import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import cn.com.tt.rmiserver.UserManagerImp; import cn.com.tt.rmiserver.stub.UserManagerInterface; public class Entry { public static void main(String []args) throws AlreadyBoundException, RemoteException{ UserManagerImp userManager=new UserManagerImp(); UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0); // Bind the remote object's stub in the registry Registry registry = LocateRegistry.createRegistry(2002); registry.rebind("userManager", userManagerI); System.out.println("server is ready"); } }
(4) Client-Code
1、把Server端的Account类和接口UserManagerInterface 导出Export成jar包,命名为:RmiServerInterface.jar。导入到client中。
2、项目——右键——Export——java——jar file——next——选择Account类和接口UserManagerInterface——命名为:RmiServerInterface.jar如下图:
3. 新建一个java Project,导入jar包,编写客户端代码。
4. 代码
ClientEntry.java
package weiblog.rmi; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import cn.com.tt.rmiserver.stub.UserManagerInterface; public class ClientEntry { public static void main(String []args){ try { Registry registry = LocateRegistry.getRegistry("localhost",2004); UserManagerInterface userManager = (UserManagerInterface)registry.lookup("userManager"); System.out.println("用户名是"+userManager.getAdminAccount().getUsername() +"密码"+userManager.getAdminAccount().getPassword()); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NotBoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
5. 先运行服务器端代码, 然后运行客户端代码,就会显示运行结果,客户端可以运行多次,每次都可以取得服务器端的对象。如果要再次运行客户端代码就需要更改端口号,如果不更改就会显示端口号被占用。
更多java知识请关注java基础教程栏目。
Das obige ist der detaillierte Inhalt vonDetaillierte grafische Erklärung von Java RMI (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!