1

我目前正在使用 SpringRmiProxyFactoryBean来访问远程服务。由于需求发生了变化,我需要在运行时指定一个不同的主机 - 可以有很多 - ,但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 文件中生成它。

4

2 回答 2

2

如果查看 RmiProxyFactoryBean 的源代码,可以看到它是 RmiClientInterceptor 的一个非常瘦的子类,它只是一个标准的 AOP MethodInterceptor。这对我来说建议您可以编写一个自定义类来实现您想要的getServiceFor(hostname)方法,并且该方法可以使用 Spring ProxyFactory 以类似于 RmiProxyFactoryBean 的方式为您的特定主机生成运行时代理。

例如:

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();
}

WherermiServiceInterfaceproxyInterfaceare 类型由您定义。

于 2009-08-12T09:50:35.340 回答
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();
  }
}

当然,这涉及到一些健全性检查和缓存,但我已经省略了它们。

于 2009-08-12T12:13:11.420 回答