2009-08-12 90 views
1

我目前使用Spring RmiProxyFactoryBean来访问远程服务。由于需求已更改,因此我需要在运行时指定不同的主机 - 可能有很多主机 - ,但和remoteServiceUrl的非主机组件保持不变。Spring中的RMIPRoxyFactoryBean工厂?

从概念上来讲,我看到类似的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); 

是否有提供此类服务有春天吗?或者,你是否看到了另一种做法?


请注意,主机列表将在编译或启动时间已知,所以我不能在xml文件中生成它。

回答

0

我结束了implemeting类似于:

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

当然,有一些健全检查和缓存涉及,但我已经中省略他们。

1

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

例如:

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是类型由您定义。