我目前正在使用Spring RmiProxyFactoryBean
来访问远程服务。由于需求已经改变,我需要在运行时指定一个不同的主机 - 可能有很多主机 - 但remoteServiceInterface
和remoteServiceUrl
的非主机组件保持不变。
从概念上讲,我会看到类似于:
的bean定义<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBeanFactory">
<property name="serviceInterface" value="xxx"/>
<property name="serviceUrl" value="rmi://#{HOST}:1099/ServiceUrl"/>
</bean>
暴露了
Object getServiceFor(String hostName);
Spring有这样的服务吗?或者,您是否看到了另一种方法?
请注意,主机列表不会在编译或启动时知道,所以我无法在xml文件中生成它。
答案 0 :(得分:2)
如果查看RmiProxyFactoryBean的源代码,可以看到它是RmiClientInterceptor的一个非常薄的子类,它只是一个标准的AOP MethodInterceptor。这告诉我,您可以编写一个实现所需getServiceFor(hostname)
方法的自定义类,并且此方法可以使用类似于RmiProxyFactoryBean的Spring ProxyFactory,为您的特定主机生成运行时代理。 / p>
例如:
public Object getProxyFor(String hostName) {
RmiClientInterceptor rmiClientInterceptor = new RmiClientInterceptor();
rmiClientInterceptor.setServiceUrl(String.format("rmi://%s:1099/ServiceUrl", hostName));
rmiClientInterceptor.setServiceInterface(rmiServiceInterface);
rmiClientInterceptor.afterPropertiesSet();
return new ProxyFactory(proxyInterface, rmiClientInterceptor).getProxy();
}
rmiServiceInterface
和proxyInterface
是您定义的类型。
答案 1 :(得分:0)
我最终实现了类似的东西:
public class RmiServiceFactory implements BeanClassLoaderAware {
public Service getServiceForHost(String hostName) {
factory = new RmiProxyFactoryBean();
factory.setLookupStubOnStartup(false);
factory.setRefreshStubOnConnectFailure(true);
factory.setServiceInterface(Service.class);
factory.setServiceUrl(String.format(_serviceUrlFormat, hostName));
if (_classLoader != null)
factory.setBeanClassLoader(_classLoader);
factory.afterPropertiesSet();
}
}
当然,有一些健全性检查和缓存,但我省略了它们。