Java远程方法调用(Java Remote Method Invocation, RMI)支持一个JVM中的对象调用另一个JVM对象的方法,而这两个JVM可以分布在不同的主机上,为Java的分布式应用提供了支持。
1.首先,定义一个远程调用接口,该接口必须实现java.rmi.Remote接口,接口的方法声明要抛出java.rmi.RemoteException
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloRemote extends Remote {
String sayHello(UserRemote user)throws RemoteException;
}
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 3553604278956856032L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.实现接口并继承UnicastRemoteObject
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloRemoteImpl extends UnicastRemoteObject implements HelloRemote {
private static final long serialVersionUID = -6209023821784985143L;
protected HelloRemoteImpl() throws RemoteException {
super();
}
@Override
public String sayHello(User user) throws RemoteException {
return "Hello, " + user.getName();
}
}
3.注册该服务并启动
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class RemoteServer {
public static void main(String[] args) {
try {
// System.setProperty("java.rmi.server.hostname", "10.0.0.249");
LocateRegistry.createRegistry(5590);
HelloRemoteImpl server = new HelloRemoteImpl();
Naming.rebind("//10.0.0.249:5590/HelloRemote", server);
System.out.println("server start……");
} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
5.调用RMI服务
package com.lanhuidong.client;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class RMIClient {
public static void main(String[] args) {
String url = "//10.0.0.249:5590/HelloRemote";
try {
HelloRemote helloRemote = (HelloRemote) Naming.lookup(url);
User user = new User();
user.setName("RMI");
System.out.println(helloRemote.sayHello(user));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
在实际项目中,可能项目使用了Spring等框架,下面是spring的rmi服务
1定义接口(不用继承任何其它接口)
public interface UserRmiService {
public String sayHello(User user);
}
import java.io.Serializable;
public class User implements Serializable{
private static final long serialVersionUID = 8550373205815267923L;
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
2.实现该接口
public class UserRmiServiceImpl implements UserRmiService {
@Override
public String sayHello(User user) {
return "Hello, " + user.getUserName();
}
}
3.在applicationContext.xml中配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userRmiServiceImpl" class="com.darcy.rmi.service.impl.UserRmiServiceImpl"/> <bean id="userRmi" class="org.springframework.remoting.rmi.RmiServiceExporter"> <property name="service" ref="userRmiServiceImpl" /> <property name="serviceName" value="userRmi" /> <property name="serviceInterface" value="com.darcy.rmi.service.UserRmiService" /> <property name="registryPort" value="9999" /> </bean> </beans>
4.启动服务
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ServerTest {
public static void main(String[] args) {
System.setProperty("java.rmi.hostname", "10.0.0.249");
new ClassPathXmlApplicationContext("applicationContext-Server.xml");
System.out.println("server start......");
}
}
5.调用服务
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
UserRmiService ums = (UserRmiService) ctx.getBean("rmiProxy");
User user = new User();
user.setUserName("RMI");
System.out.println(ums.sayHello(user));
}
}
applicationContext-client.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="rmiProxy" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> <property name="serviceUrl" value="rmi://127.0.0.1:9999/userRmi"/> <property name="ServiceInterface" value="com.darcy.rmi.service.UserRmiService" /> </bean> </beans>