动态远程服务定位 - 如何使用Spring注入?

时间:2012-03-16 18:45:33

标签: java spring rmi soa spring-remoting

我目前正致力于为工作中的项目开发分布式服务架构。从本质上讲,我们管理着超过200台机器。这些机器中的每一台都有一个运行服务的实例,允许我们以特定的方式与机器连接。

在中心,我有一个控制应用程序,需要与这200个相同的服务进行对话。我希望通过Spring Remoting使用RMI来实现这一点,允许我将@Autowire我的远程服务放入我的@Controller并将其视为具有异常传播的本地服务,并且可能在将来通过钩子传播事务/安全上下文。

这适用于单个机器上的单个服务,我可以在Spring配置中对远程服务进行硬编码,但我无法弄清楚的是如何动态选择哪个服务(也就是哪个服务器)我想在运行时与之交谈并使该远程服务可用于" Spring"方式。

我希望能够从数据库表中动态配置它,并使用相同的表信息进行服务查找,同时仍然利用依赖注入。

我想过可能会注入一些可以进行某种服务查询的服务管理器,但希望其他人能够优雅地解决这个(或类似的)问题。

硬编码的单一服务实例的示例如下:

第一个XML片段在机器服务本身上,告诉Spring通过RMI公开它

<!-- Expose DeviceService via RMI -->
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
    <property name="serviceName" value="DeviceService" />
    <property name="service" ref="deviceService" />
    <property name="serviceInterface"
        value="com.example.service.DeviceService" />
    <property name="registryPort" value="1199" />
</bean>

第二个XML片段位于客户端(控制应用程序)上,它允许我访问公开的服务

<!-- Proxy our remote DeviceService via RMI -->
<bean id="remoteDeviceService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    <property name="serviceUrl" value="rmi://machineurl:1199/DeviceService"/>
    <property name="serviceInterface" value="com.example.service.DeviceService"/>
</bean>

这是我试图制作动态的第二位配置。如您所见,要创建此服务代理,我需要在bean创建时知道服务URL。服务URL可以是200多种变体中的一种,具体取决于我想要与之交谈的机器。我正在谈论的服务是相同的界面,但我不知道哪个机器直到运行时取决于当前的请求上下文。

1 个答案:

答案 0 :(得分:2)

您可以使用其他服务动态创建与服务器的连接,并从客户端/控制应用程序中删除“remoteDeviceService”,即:

public class RMIConnectionService {

    public DeviceService connect(String serverUrl) {
        RmiProxyFactoryBean factory = new RmiProxyFactoryBean();
        factory.setServiceInterface(DeviceService.class);
        factory.setServiceUrl("rmi://" + serverUrl + ":1099/SERVICE_URL");
        factory.afterPropertiesSet();
        //...
        return (DeviceService) factory.getObject();
    }
}

然后将此服务添加到服务层:

<bean id="rmiService" class="...RMIConnectionService" >
    //...
</bean>

在您的逻辑中,自动装配服务并使用它:

DeviceService server1 = rmiService.connect("127.0.0.1");

对于数据库配置,将DAO添加到此服务,以加载正确的URL。端口和URL,甚至接口类也可以这样配置。

我没有RMI服务来测试这个,但它也适用于Hessian。我希望这会对你有所帮助。