Spring中的RMIPRoxyFactoryBean工厂?

时间:2009-08-12 09:14:57

标签: spring rmi

我目前正在使用Spring RmiProxyFactoryBean来访问远程服务。由于需求已经改变,我需要在运行时指定一个不同的主机 - 可能有很多主机 - 但remoteServiceInterfaceremoteServiceUrl的非主机组件保持不变。

从概念上讲,我会看到类似于:

的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文件中生成它。

2 个答案:

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

rmiServiceInterfaceproxyInterface是您定义的类型。

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

当然,有一些健全性检查和缓存,但我省略了它们。