远程调用,Java—RMI和Spring—RMI比较

远程调用,Java—RMI和Spring—RMIfangs     

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。JVM 可以位于相同或不同计算机上,在多个 JVM 中,一个 JVM 可以调用存储在其它 JVM 的对象的方法。
       RMI 是 Java 编程语言里,一种用于实现远程过程调用的应用程序编程接口,它是客户机上运行的程序可以调用远程服务器上的对象,远程方法调用特性使 Java 编程人员能够在网络环境中分布操作。RMI 全部的宗旨就是尽可能简化远程接口对象的使用。
       Java RMI 极大地依赖于接口,在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节,客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。
       Spring 的优势除了 IOC 和 AOP 外,还提供了简易的服务抽象。如远程 rmi 调用。 远程方法调用,即 Java RMI(javaRemote Method Invocation)。 RMI 底层封装了 Socket 反射机制。java 语言当中分布式的基础!!!实现 java 之间的互相访问。RMI 本质就是使用代理类来封装 Socket 的通信细节!!RMI 的 API 帮助我们创建一个代理类及其内容!!使用这个代理类实例就可以远程通信。

具体代码实现如下:

一、Java—RMI实现远程调用

服务器端:

1).Remote 接口:每一个要暴露出去的 java 类,都需要实现 Remote 接口,并且所有的方法必须抛出RemoteException
2).UnicastRemoteObject 类:服务端程序的实现方案之一就是继承这个类,无参构造器也要抛出 RemoteException
3).LocateRegistry 类创建能在特定接口接受调用远程对象注册服务程序。

第一个类:接口定义:

        1.定义远程接口,必须继承Remote接口,   

        2其中所有需要远程调用的方法都必须抛出RemoteException异常    

第二个类:接口具体实现服务类:

        1、继承 UnicastRemoteObject

        2、提供 无参构造 对外声明 RemoteException

第三个类:测试类

        1、 注册端口:生成远程对象注册表Registry的实例,并指定端口为8888(默认端口是1099)

        2、对外发布rmi服务:把远程对象注册到RMI注册服务器上,并命名

客户端与服务端必须声明相同接口

客户端:

第一个类:接口定义(与服务器接口一致)

1.接口继承 Remote

2.对外服务方法声明 RemoteException 异常

第二个类:客户端查找并调用远程服务

1、查找对为发布的rmi:在RMI服务注册表中查找被命名的的对象,并调用其上的方法  

代码示例:

创建java项目

服务器端:

1、定义接口HelloImpl

package com.mage.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 
 * 1接口继承Remote
 * 2方法必须抛出RemoteException异常
 * (每一个要暴露出去的 java 类,都需要实现 Remote 接口,并且所有的方法必须抛出RemoteException)
 * @author Marry
 *
 */
public interface HelloImpl extends Remote {
	public String sayHello(String msg) throws RemoteException;
}

2、定义实体类 

package com.mage.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
 * 1服务器类继承UnicastRemoteObject,并实现HelloImpl接口
 * 2实现接口中的方法,提供无参构造器
 * @author Marry
 *
 */

public class Service01 extends UnicastRemoteObject implements HelloImpl{

	private static final long serialVersionUID = 1L;
	
	protected Service01() throws RemoteException {}

	@Override
	public String sayHello(String msg) throws RemoteException {
		return "服务器接到消息:"+msg;
	}
	
}

3、服务器测试类

package com.mage.rmi;

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

/**
 * 1注册端口
 * 2对外发布rmi服务
 * @author Marry
 *
 */
public class Test {
	public static void main(String[] args) 
			throws RemoteException, MalformedURLException, AlreadyBoundException {
		//注册端口
		LocateRegistry.createRegistry(1220);
		//对外发布服务
		Naming.bind("rmi://localhost:1220/hello", new Service01());
	}
}

注意:客户端与服务端必须声明相同接口

 客户端

1、定义接口类

package com.mage.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 
 * 1接口继承Remote
 * 2方法必须抛出RemoteException异常
 * (每一个要暴露出去的 java 类,都需要实现 Remote 接口,并且所有的方法必须抛出RemoteException)
 * @author Marry
 *
 */
public interface HelloImpl extends Remote {
	public String sayHello(String msg) throws RemoteException;
}

2、客户端测试类

package com.mage.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/**
 *
 * 1接收服务器发布的rmi服务
 * @author Marry
 *
 */
public class Test {
	public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException 
	{
		HelloImpl helloImpl =(HelloImpl) Naming.lookup("rmi://localhost:1220/hello");
		//向服务器发送信息
		System.out.println(helloImpl.sayHello("你这个小兔崽子"));
	}
}

 

运行结果:

注意事项:

1、客户端和服务端创建的接口必须相同,客户端需要通过相同的接口去调用服务端的方法

2、客户端和服务端的端口号以及传过来的参数必须相同,"rmi://localhost:1220/hello"

二、Spring—RMI实现远程调用

1、使用spring_RMI实现远程调用不需要继承接口和指定的类,也不需要抛出异常,需要配置xml文件

服务器端:

1:定义一个接口,创建要实现的方法

2:实现上面的接口,重写接口中的方法

3:配置XML文件

4:测试类,获取xml文件

客户端:

1:定义一个接口,创建要实现的方法

2:配置xml文件

3:测试类:获取xml文件,获取接口bean,通过接口bean调用方法

代码示例:

创建一个Maven.project项目,两个子类Maven.modle(一个客户端,一个服务端)

服务器端:

1、配置pom.xml文件


  	
	
	    org.springframework
	    spring-context
	    4.1.6.RELEASE
	
  

 2、创建接口类

package com.mage.rmi;

import java.rmi.RemoteException;

import org.springframework.stereotype.Component;
@Component
public interface ChatImpl {
	public String sayHello(String msg);
}

3、实现接口类

package com.mage.rmi;

import org.springframework.stereotype.Service;

@Service
public class HelloService implements ChatImpl{

	@Override
	public String sayHello(String msg) {
		System.out.println("服务器接收消息是"+msg);
		return "服务器:"+msg;
	}

}

4、配置spring.xml文件





	
	
	
	
		
		
		
		
	

5、服务器测试类

package com.mage.rmi;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	public static void main(String[] args) {
		//加载spring.xml文件
		new ClassPathXmlApplicationContext("spring.xml");
	}
}

注意:客户端和服务端的接口必须相同

客户端:

1、配置pom.xml文件


  
  	
	
	    org.springframework
	    spring-context
	    4.1.6.RELEASE
	
  

2、创建接口类

package com.mage.rmi;

import java.rmi.RemoteException;

public interface ChatImpl {
	public String sayHello(String msg);
}

3、配置spring.xml文件



	
	
	
	
		
		
		
	

4、 定义一个拿到接口的类,通过接口调用方法

package com.mage.rmi;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
@Service
public class HelloService {
	@Resource
	private ChatImpl chatImpl;
	public void test() {
		System.out.println(chatImpl.sayHello("小垃圾"));
	}
}

5、客户端测试类 

package com.mage.rmi;

import java.rmi.RemoteException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	public static void main(String[] args) throws RemoteException {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
		HelloService hello = applicationContext.getBean(HelloService.class);
		hello.test();
	}
}

运行结果:

注意事项

1、客户端和服务端创建的接口必须相同,客户端需要通过相同的接口去调用服务端的方法

2、客户端和服务端的端口号以及传过来的参数必须相同,"rmi://localhost:1220/hello"

3、通过接口属性去调用到实现类的方法

 

 

 

你可能感兴趣的:(java,rmi)