只需在Joe的答案中添加一些代码。
扩展RmiServiceExporter并访问导出的对象:
public class RmiServiceExporter extends org.springframework.remoting.rmi.RmiServiceExporter {
private Object remoteService;
private String remoteServiceName;
@Override
public Remote getObjectToExport() {
Remote exportedObject = super.getObjectToExport();
if (getService() instanceof Remote && (
getServiceInterface() == null || exportedObject.getClass().isAssignableFrom(getServiceInterface()))) {
this.remoteService = exportedObject;
}
else {
ProxyFactory factory = new ProxyFactory(getServiceInterface(),
new RmiServiceInterceptor((RmiInvocationHandler) exportedObject, remoteServiceName));
this.remoteService = factory.getProxy();
}
return exportedObject;
}
public Object getRemoteService() {
return remoteService;
}
@Override
public void setServiceName(String serviceName) {
this.remoteServiceName = serviceName;
super.setServiceName(serviceName);
}
}
代理中使用的拦截器(远程服务回调):
public class RmiServiceInterceptor extends RemoteInvocationBasedAccessor
implements MethodInterceptor, Serializable {
private RmiInvocationHandler invocationHandler;
private String serviceName;
public RmiServiceInterceptor(RmiInvocationHandler invocationHandler) {
this(invocationHandler, null);
}
public RmiServiceInterceptor(RmiInvocationHandler invocationHandler, String serviceName) {
this.invocationHandler = invocationHandler;
this.serviceName = serviceName;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return invocationHandler.invoke(createRemoteInvocation(invocation));
}
catch (RemoteException ex) {
throw RmiClientInterceptorUtils.convertRmiAccessException(
invocation.getMethod(), ex, RmiClientInterceptorUtils.isConnectFailure(ex),
extractServiceUrl());
}
}
private String extractServiceUrl() {
String toParse = invocationHandler.toString();
String url = "rmi://" + StringUtils.substringBefore(
StringUtils.substringAfter(toParse, "endpoint:["), "]");
if (serviceName != null)
url = StringUtils.substringBefore(url, ":") + "/" + serviceName;
return url;
}
}
使用这个RmiServiceExporter
导出服务时,我们可以发送一个RMI回调:
someRemoteService.someRemoteMethod(rmiServiceExporter.getRemoteService());