spring包装了rmi后,使我们得到几点便利:
不用调用rmic编译stub和skeleton
不用直接实现remote接口
不需要启动命名服务rmiregistry
但,却不支持原来rmi的回调功能。查阅许多网页也不得其解。
今天,想到一招,共享出来,如果大家有好办法欢迎回贴共享。
正常做法是:
回调一般是用在一群client端需要server来通知的情况,一般server就用Vector来保存client对象。
server端需要提供一个方法,client把对象传过来后,保存到Vector中,以后就可以通知client们了:
register (ClientObject obj);
在spring里,基本做法是一样的,唯一不同是,在这个方法里,client不能传对象,我们就传一个client提供出来的rmi对象的url:
register(String url);
在client端,就如正常使用先获得server对象,再调用这个方法,注意组成url的代码:
NodeService service = (NodeService) factory.getAPIObject("nodeServiceProxy");
String name = null;
try
{
name = "rmi://" + InetAddress.getLocalHost().getHostName() + "/NodeNotifyService";
} catch (Exception ue)
{}
int result = service.registerFlower (name);
logger.info ("result="+result);
在server端registerFlower处理里,根据url动态创建这个对象,代码如下:

public class NodeServiceImpl implements NodeService
{
public static final Logger logger = LoggerFactory.getLogger(NodeServiceImpl.class);
public NodeNotifyService service = null;

public int registerFlower (String url)
{
logger.info (url);
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceInterface(NodeNotifyService.class);
logger.info ("begin set url");
rmiProxyFactoryBean.setServiceUrl(url);

try
{
logger.info ("begin set");
rmiProxyFactoryBean.afterPropertiesSet(); 
} catch (Exception ex)
{
logger.info ("exception");
} 

if (rmiProxyFactoryBean.getObject() instanceof NodeNotifyService)
{
service = (NodeNotifyService) rmiProxyFactoryBean.getObject();
}
return 0;
}
}

这样就从url转换成client对象了,当然了,还是需要在client和server各自配置文件里配置RmiServiceExporter,这一步很简单,和正常的spring的rmi是一样的了。
做到这步后,我还想把所有接口文件放到一个JAR里,client和server的实现,以及各自逻辑放到各自的JAR中,这样各自改实现就不需要两边更新包。改接口的话,就更新接口所在JAR。不知道这样安排是否合理?
本文介绍了一种在Spring框架下实现RMI回调的方法,通过传递URL而非对象的方式,解决了Spring封装RMI后不支持回调的问题。此方法在客户端和服务端均配置RmiServiceExporter的基础上,利用RmiProxyFactoryBean根据URL动态创建远程对象。
3059

被折叠的 条评论
为什么被折叠?



