RMI:remote method invocation

1、概念

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。

2、简单示例

2.1 示例一(简单RMI)

接口IHello:

package cn.edu.ecust.wzh.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * @author wzh
 * 定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常
 */
public interface IHello extends Remote{
	public String helloWorld() throws RemoteException;
	public String sayHelloToSomeBody(String someBodyName) throws RemoteException;
}
HelloImpl实现:

package cn.edu.ecust.wzh.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
 * 接口实现
 * @author wzh
 * extends UnicastRemoteObject 在普通rmi的时候需要存在,当在spring中集合多个rmi的时候不需要
 */
public class HelloImpl <span style="font-family: 宋体, 'Arial Narrow', arial, serif;">extends UnicastRemoteObject</span><span style="font-family: 宋体, 'Arial Narrow', arial, serif;"> implements IHello{</span>
	private static final long serialVersionUID = 1L;
	public HelloImpl() throws RemoteException {
	}
	@Override
	public String helloWorld() throws RemoteException {
		// TODO Auto-generated method stub
		return "Hello World!";
	}
	@Override
	public String sayHelloToSomeBody(String someBodyName) throws RemoteException {
		// TODO Auto-generated method stub
		return "你好," + someBodyName + "!";
	}
}
HelloServer:

package cn.edu.ecust.wzh.rmi;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
/**
 * @author wzh
 * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中
 */
public class HelloServer {
	public static void main(String[] args){	
		try { 
            //创建一个远程对象 
            IHello rhello = new HelloImpl(); 
            //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,
            //这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,
            //则无法绑定对象到远程注册表上 
            LocateRegistry.createRegistry(8888); 
            //把远程对象注册到RMI注册服务器上,并命名为RHello 
            //绑定的URL标准格式为:rmi://host:port/name
            //(其中协议名可以省略,下面两种写法都是正确的) 
            Naming.bind("rmi://192.168.1.123:8888/hello",rhello); 
//          Naming.bind("//localhost:8888/RHello",rhello); 
            System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); 
        } catch (RemoteException e) { 
            System.out.println("创建远程对象发生异常!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("发生重复绑定对象异常!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("发生URL畸形异常!"); 
            e.printStackTrace(); 
        }
	}
}
HelloClient:

package cn.edu.ecust.wzh.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
/**
 * @author wzh
 * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。
 */
public class HelloClient {
	public static void main(String args[]){ 
        try { 
            //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 
            IHello rhello =(IHello) Naming.lookup("rmi://192.168.1.123:8888/hello"); 
            System.out.println(rhello.helloWorld()); 
            System.out.println(rhello.sayHelloToSomeBody("熔岩")); 
        } catch (NotBoundException e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e) { 
            e.printStackTrace();   
        } 
    }
}
2.2 示例二(由spring配置RMI)

可以将多个rmi服务写到一个配置文件中,统一启动~

基于示例一中的HelloImpl和IHello作为其中的一个RMI服务,再写一个IMath和MathImpl的RMI服务

由spring配置多个rmi服务的时候,extends UnicastRemoteObject 在普通rmi的时候需要存在,当在spring中集合多个rmi的时候不需要

IMath接口:

package cn.edu.ecust.wzh.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IMath extends Remote{
	public Integer add(Integer a, Integer b) throws RemoteException;
}
MathImpl:

package cn.edu.ecust.wzh.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class MathImpl implements IMath{
	private static final long serialVersionUID = 1L;
	public MathImpl() throws RemoteException {
	}
	@Override
	public Integer add(Integer a, Integer b) throws RemoteException {
		return a+b;
	}
}
RMI服务配置:

<?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-2.0.xsd">
	
	<bean id="rmiClient_hello" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceUrl">
			<value>rmi://192.168.1.123:8888/hello</value>
		</property>
		<property name="serviceInterface">
			<value>cn.edu.ecust.wzh.rmi.IHello</value>
		</property>
	</bean>
	<bean id="rmiClient_math" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceUrl">
			<value>rmi://192.168.1.123:9999/math</value>
		</property>
		<property name="serviceInterface">
			<value>cn.edu.ecust.wzh.rmi.IMath</value>
		</property>
	</bean>
</beans>
RMI客户端配置:

<?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-2.0.xsd">
	
	<bean id="rmiClient_hello" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceUrl">
			<value>rmi://192.168.1.123:8888/hello</value>
		</property>
		<property name="serviceInterface">
			<value>cn.edu.ecust.wzh.rmi.IHello</value>
		</property>
	</bean>
	<bean id="rmiClient_math" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceUrl">
			<value>rmi://192.168.1.123:9999/math</value>
		</property>
		<property name="serviceInterface">
			<value>cn.edu.ecust.wzh.rmi.IMath</value>
		</property>
	</bean>
</beans>
服务端启动:

package cn.edu.ecust.wzh.rmi;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RmiService {
	public static void main(String[] args){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("rmi-server.xml");  
		System.out.println("RMI服务伴随Spring的启动而启动了.....");  
	}
}
客户端调用:

package cn.edu.ecust.wzh.rmi;

import java.rmi.RemoteException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RmiClient {
	/**
	 * @param args
	 * @throws RemoteException 
	 */
	public static void main(String[] args) throws RemoteException {
		// TODO Auto-generated method stub
		ApplicationContext ctx = new ClassPathXmlApplicationContext("rmi-client.xml");
		
		IHello rhello = (IHello) ctx.getBean("rmiClient_hello");
		System.out.println(rhello.sayHelloToSomeBody("海翼知"));
		
		IMath rmath = (IMath) ctx.getBean("rmiClient_math");
		System.out.println(rmath.add(1, 2));
	}
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值