您的位置:首页 > 产品设计 > UI/UE

Java中RMI应用(Ant build)

2012-08-08 23:13 267 查看
声明:本文为原创,欢迎转载,转载请注明出处。

Java的RMI(Remote Method Invocation)用于调用不同JVM上的方法,可用于分布式计算。在下面的描述中,调用方称作客户机,被调用方称作服务器。

RMI的实现机制是客户机JVM上维护一个RMI Stub(桩), 服务器JVM上维护一个RMI SKeleton(骨架), 客户对远端的方法请求会通过Stub经由网络IO传送给Skeleton,进而最终调用真正的服务对象方法。执行结果按相反的方向再传回客户端。

RMI的实现主要有一下几个步骤(参考HeadFirst 设计模式):

1> 定义远程接口。

远程接口需要扩展java.rmi.Remote,即extends Remote,远程接口里面声明会被远程调用的方法,这些方法应该抛出RemoteException的异常,并且这些方法的返回值是原语(primitive)或者可序列化(Serializable)类型。

2>实现远程接口

远程接口的实现不仅要implements步骤1中定义的远程接口,还要extends UnicastRemoteObject,由于UnicastRemoteObject的构造器会抛出RemoteException,因此实现远程接口的具体类需要设计一个无参的构造函数并抛出RemoteException异常,这个构造函数里面不需要写任何代码。

3>通过RMI Registry注册远程服务

通过java.rmi.Naming的rebind()方法实现:

Naming.rebind("服务名", 远程接口具体实现类的引用)

实例如下:

server 端:

/*
* BillRemote.java
*
* Copyright (c) 2012 Bill Sun. All rights reserved.
*/
package com.bill.test.RmiServer;

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

/**
* Interface for RMI server side.
*
* @since  1.0
* @author bill
*/
public interface BillRemote extends Remote {
public String getMyName() throws RemoteException;
}


/*
* BillRemoteImpl.java
*
* Copyright (c) 2012 Bill Sun. All rights reserved.
*/
package com.bill.test.RmiServer;

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

/**
* Implementation for RMI server side.
*
* @since  1.0
* @author bill
*/
public class BillRemoteImpl extends UnicastRemoteObject implements BillRemote {

public BillRemoteImpl () throws RemoteException {}

public String getMyName() throws RemoteException {
return "Dong.";
}
}

/*
* RMIServer.java
*
* Copyright (c) 2012 Bill Sun. All rights reserved.
*/
package com.bill.test.RmiServer;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

/**
* RMI server.
*
* @since  1.0
* @author bill
*/
public class RMIServer {

public static void main (String[] args) {
try {
LocateRegistry.createRegistry(1099);
BillRemote service = new BillRemoteImpl();
Naming.rebind("rmi://192.168.2.4:1099/billRMI", service);
System.out.println("RMI server is ready.");

} catch (Exception e) {
e.printStackTrace();
}
}
}


ant build脚本:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_jar" name="build RMI client and server">

<property name="package.dir"    value="D:/Bill/Dev/test"/>

<target name="build_RMI">
<echo message="Building RMI"/>
<javac destdir="${package.dir}/bin" srcdir="${package.dir}/src" />
</target>

<target name="create_jar" depends="clean_all, build_RMI">
<echo message="creating jar"/>

<jar destfile="${package.dir}/bin/RmiServer.jar" >
<zipfileset dir="${package.dir}/bin" includes="com/bill/test/RmiServer/*.class" />
<manifest>
<attribute name="Main-class" value="com.bill.test.RmiServer.RMIServer"/>
<attribute name="Class-Path" value="."/>
</manifest>
</jar>
</target>

<target name="clean_all">
<echo message="Cleaning all"/>
<delete>
<fileset dir="${package.dir}/bin" />
</delete>
</target>

</project>


client端:

/*
* BillRemoteImpl.java
*
* Copyright (c) 2012 Bill Sun. All rights reserved.
*/
package com.bill.test.RmiClient;

import java.rmi.Naming;

import com.bill.test.RmiServer.BillRemote;

/**
* RMI client side.
*
* @since  1.0
* @author bill
*/
public class RMIClient {
public static void main (String[] args) {
try {
BillRemote remoteService = (BillRemote) Naming.lookup("rmi://192.168.2.4/billRMI");
String myName = remoteService.getMyName();
System.out.println(myName);
} catch (Exception e) { e.printStackTrace(); }
}
}


值得注意的是,如果client与server都在同一台机器上,那么client端可以为
(BillRemote) Naming.lookup("rmi://127.0.0.1/billRMI");
server端为:

Naming.rebind("billRMI", service);
但是server端与client不在同一台机器时,rebind里必须有server的IP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息