Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。

  一、创建RMI程序的4个步骤

    1、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。

    2、定义一个实现该接口的类。

    3、创建一个服务,用于发布2中定义的类。

    4、创建一个客户程序进行RMI调用。

  二、程序的详细实现

    1.首先我们先创建一个实体类,这个类需要实现Serializable接口,用于信息的传输。    

 import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

    2.定义一个接口,这个接口需要继承Remote接口,这个接口中的方法必须声明RemoteException异常。

 import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
public interface StudentService extends Remote {
List<Student> getList() throws RemoteException;
}

    3.创建一个类,并实现步骤2中的接口,但还需要继承UnicastRemoteObject类和显示写出无参的构造函数。

 import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
public class StudentServiceImpl extends UnicastRemoteObject implements
StudentService {
public StudentServiceImpl() throws RemoteException {
}
public List<Student> getList() throws RemoteException {
List<Student> list=new ArrayList<Student>();
Student s1=new Student();
s1.setName("张三");
s1.setAge(15);
Student s2=new Student();
s2.setName("李四");
s2.setAge(20);
list.add(s1);
list.add(s2);
return list;
}
}

    4.创建服务并启动服务

 import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class SetService {
public static void main(String[] args) {
try {
StudentService studentService=new StudentServiceImpl();
LocateRegistry.createRegistry(5008);//定义端口号
Naming.rebind("rmi://127.0.0.1:5008/StudentService", studentService);
System.out.println("服务已启动");
} catch (Exception e) {
e.printStackTrace();
}
}
}

    5. 创建一个客户程序进行RMI调用。

 import java.rmi.Naming;
import java.util.List;
public class GetService {
public static void main(String[] args) {
try {
StudentService studentService=(StudentService) Naming.lookup("rmi://127.0.0.1:5008/StudentService");
List<Student> list = studentService.getList();
for (Student s : list) {
System.out.println("姓名:"+s.getName()+",年龄:"+s.getAge());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

    6.控制台显示结果

      =============控制台============

      姓名:张三,年龄:15

      姓名:李四,年龄:20

      ===============================

在Spring中配置Rmi服务

  将Rmi和Spring结合起来用的话,比上面实现Rmi服务要方便的多。

  1.首先我们定义接口,此时定义的接口不需要继承其他接口,只是一个普通的接口

 package service;
import java.util.List;
public interface StudentService {
List<Student> getList();
}

  2.定义一个类,实现这个接口,这个类也只需实现步骤一定义的接口,不需要额外的操作

 package service;
import java.util.ArrayList;
import java.util.List;
public class StudentServiceImpl implements StudentService {
public List<Student> getList() {
List<Student> list=new ArrayList<Student>();
Student s1=new Student();
s1.setName("张三");
s1.setAge(15);
Student s2=new Student();
s2.setName("李四");
s2.setAge(20);
list.add(s1);
list.add(s2);
return list;
}
}

  3.接一下来在applicationContext.xml配置需要的信息

    a.首先定义服务bean    

<bean id="studentService" class="service.StudentServiceImpl"></bean>

    b.定义导出服务

      <bean class="org.springframework.remoting.rmi.RmiServiceExporter"
        p:service-ref="studentService"
        p:serviceInterface="service.StudentService"
        p:serviceName="StudentService"
        p:registryPort="5008"
      />

      也可以增加p:registryHost属性设置主机

    c.在客户端的applicationContext.xml中定义得到服务的bean(这里的例子是把导出服务bean和客户端的bean放在一个applicationContext.xml中的)

 <bean id="getStudentService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
p:serviceUrl="rmi://127.0.0.1:5008/StudentService"
p:serviceInterface="service.StudentService"
/>

    d.配置的东西就这么多,是不是比上面的现实要方便的多呀!现在我们来测试一下

 package service;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService=(StudentService) ctx.getBean("getStudentService");
List<Student> list = studentService.getList();
for (Student s : list) {
System.out.println("姓名:"+s.getName()+",年龄:"+s.getAge());
}
}
}

      =============控制台============
      姓名:张三,年龄:15
      姓名:李四,年龄:20
      =============================
      上面的mian方法运行可能会报错,应该是spring的jar少了,自己注意添加。

第一次写博客,有不对的地方请多多指出。

Java学习之路-RMI学习的更多相关文章

  1. 《Hadoop学习之路》学习实践

    (实践机器:blog-bench) 本文用作博文<Hadoop学习之路>实践过程中遇到的问题记录. 本文所学习的博文为博主“扎心了,老铁” 博文记录.参考链接https://www.cnb ...

  2. Java学习之路-Hessian学习

    Hessian是基于HTTP的轻量级远程服务解决方案,Hessian像Rmi一样,使用二进制消息进行客户端和服务器端交互.但与其他二进制远程调用技术(例如Rmi)不同的是,它的二进制消息可以移植其他非 ...

  3. (转)java web 学习之路(学习顺序)

    第一步:学习HTML和CSS HTML(超文本标记语言)是网页的核心,学好HTML是成为Web开发人员的基本条件.HTML很容易学习的,但也很容易误用,要学精还得费点功夫. 随着HTML5的发展和普及 ...

  4. Java学习之路-Burlap学习

    今天我们来学一下Burlap. Burlap是一种基于XML远程调用技术,但与其他基于XML的远程技术(例如SOAP或者XML-RPC)不同,Burlap的消息结构尽可能的简单,不需要额外的外部定义语 ...

  5. 微软企业库5.0 学习之路——扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]

    这篇文章是我在patterns & practices看到的一篇有关EntLib5.0的文章,主要介绍了EntLib5.0的这次的架构变化由来,觉得很不错,大家可以看一下! 在过去几年中,依赖 ...

  6. 《Hadoop学习之路》学习实践二——配置idea远程调试hadoop

    背景:在上篇文章中按照大神“扎心了老铁”的博客,在服务器上搭建了hadoop的伪分布式环境.大神的博客上是使用eclipse来调试,但是我入门以来一直用的是idea,eclipse已经不习惯,于是便摸 ...

  7. Linux学习之路--shell学习

    shell基础知识 什么是Shell Shell是命令解释器(command interpreter),是Unix操作系统的用户接口,程序从用户接口得到输入信息,shell将用户程序及其输入翻译成操作 ...

  8. Java程序员学习之路

    1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基 ...

  9. (转)如何学习Java技术?谈Java学习之路

    51CTO编者注:这篇文章已经是有数年“网龄”的老文,不过在今天看来仍然经典.如何学习Java?本篇文章可以说也是面对编程初学者的一篇指导文章,其中对于如何学习Java的步骤的介绍,很多也适用于开发领 ...

随机推荐

  1. [XPath] XPath 与 lxml (二)XPath 语法

    XPath 选取节点时使用的表达式是一种路径表达式.节点是通过路径(path)或者步(steps)来选取的. 本章使用以下 XML 文档作为示例. <?xml version="1.0 ...

  2. 嵌入式之UBOOT

    嵌入式Linux系统的结构分为四个区,如图所示: 1.Bootloader区存放的是Bootloader,Coidre972开发板上使用的uboot,它负责嵌入式系统最初的硬件初始化.驱动和内核加载. ...

  3. 在input中既隐藏边框,也隐藏轮廓的设置

    在设置input的时候,我们往往不想显示边框,所以通常会在css里面写"border"none",但是结果往往差强人意,如下图 我们这个时候可以加一个属性来把它的轮廓也隐 ...

  4. MyEclipse 10 下在线安装插件

    昨天不知道怎么就删除了电脑中的eclipse 我x,还原不回来了. 今天就安装了最新版本的myeclipse10,大家都知道,MyEclipse 中有一个烦人的 Software and Worksp ...

  5. ios设备唯一标识获取策略

    In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02 ...

  6. 题目1457:非常可乐(广度优先遍历BFS)

    题目链接:http://ac.jobdu.com/problem.php?pid=1457 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  7. [转]F5负载均衡名词LTM和GTM

    LTM就是本地流量管理,也就是通常所说的服务器负载均衡.可以将多个提供相同服务的设备(pool)虚拟成一个逻辑设备,供用户访问.也就是说,对于用 户来讲,看到的只有一个设备,而实际上用户是服务请求是在 ...

  8. 游戏AI-行为树

    参考: 游戏AI—行为树研究及实现 GAD腾讯游戏开发者平台:游戏中的人工智能AI 腾讯开源项目behaviac 占坑,待编辑

  9. 【CF888E】Maximum Subsequence 折半搜索

    [CF888E]Maximum Subsequence 题意:给你一个序列{ai},让你从中选出一个子序列,使得序列和%m最大. n<=35,m<=10^9 题解:不小心瞟了一眼tag就一 ...

  10. python-django开发学习笔记二

    1.简述 1.1 开发环境 该笔记所基于的开发环境为:windows8.python2.7.5.psycopg2-2.4.2.django1.5.4.pyCharm-2.7.3.以上所描述的软件.插件 ...