欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RMI远程方法调用

程序员文章站 2022-05-12 18:51:55
...
转载请出自出处:http://eksliang.iteye.com/blog/2267510

一、概述

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。Java RMI不是什么新技术,在Java1.1的时代都有了,大名鼎鼎的EJB都是建立在rmi基础之上的,现在还有一些开源的远程调用组件,其底层技术也是rmi。

 在大力鼓吹Web Service、SOA的时代,是不是每个应用都应该选用笨拙的Web Service组件来实现,通过对比测试后,RMI是最简单的,在一些小的应用中是最合适的。

但是RMI有如下两点局限性

  • RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。
  • 是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,

 

二、使用RMI发布服务

2.1、定义RMI服务接口UserService类

 

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import com.gosun.jws.daomain.Users;

/**
 * <pre>
 * 最原始的RMI远程方法调用,
 * 发布接口必须继承Remote接口进行标识
 * 该接口所有方法必须抛出throws RemoteException异常
 * </pre>
 * @author Ickes
 */
public interface UserService extends Remote {
	/**
	 * 测试返回list
	 * 
	 * @return
	 */
	public List<Users> geAlltUsers() throws RemoteException;

	/**
	 * 测试返回实体,以及传人普通参数
	 * 
	 * @param id
	 * @return
	 */
	public Users getUser(String id) throws RemoteException;

	/***
	 * 测试传入对象
	 * 
	 * @param user
	 */
	public void save(Users user)throws RemoteException;

	/**
	 * 测试传人集合
	 * 
	 * @param users
	 */
	public void saves(List<Users> users) throws RemoteException;
}

 

2.2、UserService服务实现类

 

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import com.gosun.jws.daomain.Users;
import com.gosun.jws.daomain.UsersFactory;

/**
 * UserService接口的实现接口
 * @author Ickes
 */
public class UserServiceImpl extends UnicastRemoteObject implements UserService{
	private static final long serialVersionUID = 1L;
	protected UserServiceImpl() throws RemoteException {
		super();
	}

	@Override
	public List<Users> geAlltUsers() {
		return UsersFactory.getUsers();
	}

	@Override
	public Users getUser(String id) {
		System.out.println(id);
		return UsersFactory.getUser();
	}

	@Override
	public void save(Users user) {
		System.out.println(user.toJson());
	}

	@Override
	public void saves(List<Users> users) {
		for (Users u : users) {
			System.out.println(u.toJson());
		}
	}

}

   测试用到的:UsersFactory工具类和Users实体类在:http://eksliang.iteye.com/blog/2265021篇文章的3.1和3.2代码中

 

 

2.3、启动RMI服务,进行注册

 

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/**
 * 纯Java编写服务端代码如下
 * @author Ickes
 * 
 */
public class ServiceDemo {
	public static void main(String[] args) {
		try {
			UserService userService = new UserServiceImpl();
			//注册通讯端口,该端口默认就是1099
			LocateRegistry.createRegistry(1099);
			//注册通讯路径
			Naming.rebind("rmi://127.0.0.1:1099/UserService", userService);
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

	}
}

 

 

三.客户端调用

 

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;
import com.gosun.jws.daomain.Users;

/**
 * 纯JAVA客户端调用代码
 * @author Ickes
 */
public class ClientDemo {
	public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
		 UserService us = (UserService) Naming.lookup("rmi://127.0.0.1:1099/UserService");
		 Users user = us.getUser("a001");
			System.out.println(user.toJson());
			System.out.println("----------------------------------------");
			List<Users> users = us.geAlltUsers();
			for (Users u : users) {
				System.out.println(u.toJson());
			}
			System.out.println("----------------------------------------");
			us.save(user);
			System.out.println("----------------------------------------");
			us.saves(users);
	}
}

 

 

四、与Spring集成发布RMI服务

4.1配置spring的RmiServiceExporter

在classpath目录下面新建applicationContext-rmi.xml文件,文件内容如下:

 

	<!-- 在Spring中装配RMI服务 -->
	<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
		<!--需要发布的实现类 -->
		<property name="service" ref="userService" />
		<!-- 注册到rmi上面的名字 -->
		<property name="serviceName" value="UserService" />
		<!-- 接口完整类名 -->
		<property name="serviceInterface" value="com.gosun.jws.rmi.UserService" />
		<!-- 默认是localhost,如果是localhost就不要填写,如果填写反而报错 
		<property name="registryHost" value="localhost" />
		-->
		<!-- 默认为1099 -->
		<property name="registryPort" value="1199" />
	</bean>
	<bean id="userService" class="com.gosun.jws.rmi.UserServiceImpl" />

 4.2发布

让spring加载applicationContext-rmi.xml这个文件便完成了对RMI服务的启动。这里不累赘!

 

 

 

五、与Spring集成调用RMI服务

5.1配置Spring的RmiProxyFactoryBean

在spring中调用RMI也非常的简单,使用Spring的RmiProxyFactoryBean,该类是一个工厂对象,可以为RMI服务创建代理。使用也非常简单,在classpath下面创建client/applicationContext-rmi.xml文件,内容如下:

 

	<!-- 使用spring调用RMI的服务 -->
	<bean id="userService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<property name="serviceUrl" value="rmi://localhost:1199/UserService"/>
		<property name="serviceInterface" value="com.gosun.jws.rmi.UserService" />
	</bean>

 

5.2、客户端调用

public class ClientDemo {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("client-application/applicationContext-rmi.xml");
		UserService us = (UserService) ac.getBean("userService");
		Users user = us.getUser("a001");
		System.out.println(user.toJson());
		System.out.println("----------------------------------------");
		List<Users> users = us.geAlltUsers();
		for (Users u : users) {
			System.out.println(u.toJson());
		}
		System.out.println("----------------------------------------");
		us.save(user);
		System.out.println("----------------------------------------");
		us.saves(users);
	}
}

 

 

 

 

 

 

相关标签: RMI