2009-08-12 91 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是類型由您定義。