Java RMI技術以及Spring封裝了的RMI技術

 

       最近應用到了Java RMI技術,所以總結一下RMI的使用,另外EJB的實現也是以Java RMI爲基礎核心的。RMI遠程方法調用,可以跨機器通過網絡調用,不過Java RMI只支持兩邊都是Java程序,如果要實現完全兩邊異構,那麼就要用到傳說中的Web Service了。爲了看好效果,都要建立兩個或兩個以上工程,當然,如果你有兩個機器並通過局域網相連更好,如果能同有互聯網的條件就更好了,以下是同一機器不同工程的實驗

Java RMI

首先新建一個工程,隨便什麼工程,爲了方便,就Java Project吧。

1、創建一個接口,繼承Remote

package leon.rmi.iface;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
* 定義遠程接口,必須繼承Remote接口,
* 其中所有需要遠程調用的方法都必須拋出RemoteException異常 
*/ 
public interface IHello extends Remote { 
    public String sayHello(String name) throws RemoteException; 
    public int sum(int a, int b)throws RemoteException;
}

2、創建接口的實現類

package leon.rmi.impl;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import leon.rmi.iface.IHello;

public class HelloImpl extends UnicastRemoteObject implements IHello {

	private static final long serialVersionUID = 1L;

	public HelloImpl() throws RemoteException {
		super();
	}

	@Override
	public String sayHello(String name) throws RemoteException {
		return "Welcome, " + name;
	}

	@Override
	public int sum(int a, int b) throws RemoteException{
		return a + b;
	}
}

說明:接口的實現類同時要實現Serializable接口,這裏繼承UnicastRemoteObject也是間接實現Serializable接口,同時,因爲構造方法需要拋出RemoteException,所以不能缺省使用隱含的無參構造方法,而應該自己顯式定義構造方法。

 

3、創建應用類,註冊和啓動服務端RMI,以被客戶端調用

package leon.rmi.impl;

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

import leon.rmi.iface.IHello;

public class HelloServer {
	public static void main(String args[]) {
		try {
			//創建一個遠程對象
			IHello rhello = new HelloImpl();	
			//生成遠程對象註冊表Registry的實例,並指定端口爲8888(默認端口是1099)
			LocateRegistry.createRegistry(8888);

			//把遠程對象註冊到RMI註冊服務器上,並命名爲RHello
			//綁定的URL標準格式爲:rmi://host:port/name(協議名可以省略,下面兩種寫法都可以)
			Naming.bind("rmi://10.225.112.86:8888/RHello", rhello);
			//Naming.bind("//10.225.112.86: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();
		}
	}
}

說明:綁定的地址10.225.112.86是我的局域網地址可以在DOS命令行用ipconfig查看,如果你的機器沒有任何聯網,可以使用127.0.0.1或localhost。

運行HelloServer.java看到,紅色方塊顯示正在運行:

        >>INFO:遠程IHello對象綁定成功!

好了,現在遠程服務提供端建立完成,下面建立客戶端。

新建一個新的工程,爲了方便,也是Java Project吧,

1、 因爲客戶端需要有服務端那邊提供的接口,纔可以訪問,所以要將服務端的IHello接口完全拷貝(連同包)到客戶端,當然爲了方便,你在客戶端工程中新建一個完全一樣的接口也可以。實際運用中通常是要服務端接口打成jar包來提供的。

2、 創建客戶端調用類

package testrmi;

import java.rmi.Naming;

import leon.rmi.iface.IHello;

public class HelloClient {
	public static void main(String args[]) {
		try {
			// 在RMI服務註冊表中查找名稱爲RHello的對象,並調用其上的方法
			IHello rhello = (IHello) Naming.lookup("rmi://10.225.112.86:8888/RHello");
			System.out.println(rhello.sayHello("水哥"));
			System.out.println(rhello.sum(454, 5457));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

運行,顯示,成功。

呵呵,是不是很簡單?對吧。

下面我們要使用Spring封裝的Java RMI技術,也是很多項目都會用到的。後面我有個Spring RMI的例子。要看懂下面Spring的例子,你需要已經會用Spring,會配置Spring,否則怕你看不懂,所以如果還不懂Spring的,先學學Spring,入下門吧。

Spring RMI

       Spring RMI中,主要有兩個類:org.springframework.remoting.rmi.RmiServiceExporterorg.springframework.remoting.rmi.RmiProxyFactoryBean

服務端使用RmiServiceExporter暴露RMI遠程方法,客戶端用RmiProxyFactoryBean間接調用遠程方法。

 

   首先,也是兩個工程,服務端用Web工程,因爲使用Spring,我們依託Web容器來完成。

1、在該服務端Web工程中添加接口,普通接口,無需繼承其他

package leon.rmi.iface;

public interface IUserDao {
	public String getUserList();
	public int sum(int a, int b);
}

  2、接口的實現類

package leon.rmi.impl;

import leon.rmi.iface.IUserDao;

public class UserDaoImpl implements IUserDao {

	@Override
	public String getUserList() {
		return "Hello,Get the user list from database!";
	}

	@Override
	public int sum(int a, int b) {
		return a+b;
	}
}

3、在該服務端Web工程中添加Springbean配置文件,比如命名爲rmi.xml,內容如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="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
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<beans:bean id="userDaoRmi" class="leon.rmi.impl.UserDaoImpl"> 
    </beans:bean> 
    
	<beans:bean id="userSvcExporter" class="org.springframework.remoting.rmi.RmiServiceExporter"> 
        <beans:property name="service" ref="userDaoRmi"/> 
        <beans:property name="serviceName" value="userDaoService"/> 
        <beans:property name="serviceInterface" value="leon.rmi.iface.IUserDao"/> 
        <beans:property name="registryPort" value="9111"/> 
        <beans:property name="servicePort" value="10023"/> 
    </beans:bean> 
</beans:beans>

   說明:這裏不詳細的說明了,主要配置了真實實現類,用RmiServiceExporter暴露時,配置property要注意的有service,serviceName,serviceInterface,端口registryPort。

   啓動Web工程的服務器,該配置文件應該被Spring的監聽器監聽,並加載,啓動成功後,服務端就算建好了。如果服務器是在localhost啓動的,那麼暴露的RMIIP也是localhost,如果需要使用其他IP,需要讓服務器在其他的IP啓動。

好了,吃完午飯繼續寫
客戶端調用

爲了方便也只新建一個簡單的Java Project,使用靜態的java代碼來調用了。

1、 在源文件src下建立一個springbeans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="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
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    
	<beans:bean id="userDaoProxy" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> 
		<beans:property name="serviceUrl" value="rmi://localhost:9111/userDaoService"/> 
        <beans:property name="serviceInterface" value="leon.rmi.iface.IUserDao"/> 
    </beans:bean>
    
</beans:beans>

這裏注意到RmiProxyFactoryBean的兩個重要的property:serviceUrlserviceInterface,IUserDao接口可以從服務端的接口打成jar包來提供。

 

2、 新建java類

package testrmi;

import leon.rmi.iface.IUserDao;

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

public class TestRMI2 {
	public static void main(String[] args) {
		 ApplicationContext ctx = new ClassPathXmlApplicationContext("springbeans.xml");
		 IUserDao userDao = (IUserDao) ctx.getBean("userDaoProxy");
		 System.out.println(userDao.getUserList());
		 System.out.println(userDao.sum(145, 487));
	}
}

運行,成功。

好了,這就是一個採用Spring封裝的RMI的例子,項目工作中應該經常使用的。

有什麼問題,歡迎討論交流。



 

 




 

 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章