Spring集成–使用RMI通道适配器

1.引言

本文介绍了如何使用Spring Integration RMI通道适配器通过RMI发送和接收消息。 它由以下部分组成:

  • 实施服务:第一部分着重于创建和公开服务。
  • 实现客户端:显示如何使用MessagingTemplate类调用服务。
  • 抽象SI逻辑:最后,我添加了另一部分来说明如何实现抽象所有Spring Integration代码的同一客户机,而使客户机专注于其业务逻辑。

您可以在github上获取源代码。

2.实施服务

第一部分非常简单。 该服务是通过注释定义的,因此它将通过组件扫描自动检测。 它注入了一个存储库,该存储库从嵌入式数据库获取数据,这将在同一部分中显示:

@Service("defaultEmployeeService")
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public Employee retrieveEmployee(int id) {
        return employeeRepository.getEmployee(id);
    }
}

存储库如下:

@Repository
public class EmployeeRepositoryImpl implements EmployeeRepository {
    private JdbcTemplate template;
    private RowMapper<Employee> rowMapper = new EmployeeRowMapper();
    private static final String SEARCH = "select * from employees where id = ?";
    private static final String COLUMN_ID = "id";
    private static final String COLUMN_NAME = "name";

    @Autowired
    public EmployeeRepositoryImpl(DataSource dataSource) {
        this.template = new JdbcTemplate(dataSource);
    }

    public Employee getEmployee(int id) {
        return template.queryForObject(SEARCH, rowMapper, id);
    }

    private class EmployeeRowMapper implements RowMapper<Employee> {
        public Employee mapRow(ResultSet rs, int i) throws SQLException {
            Employee employee = new Employee();
            employee.setId(rs.getInt(COLUMN_ID));
            employee.setName(rs.getString(COLUMN_NAME));

            return employee;
        }
    }
}

以下配置通过RMI公开服务:

服务器配置文件

<context:component-scan base-package="xpadro.spring.integration"/>

<int-rmi:inbound-gateway request-channel="requestEmployee"/>

<int:channel id="requestEmployee"/>

<int:service-activator method="retrieveEmployee" input-channel="requestEmployee" ref="defaultEmployeeService"/>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- in-memory database -->
<jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:db/schemas/schema.sql" />
    <jdbc:script location="classpath:db/schemas/data.sql" />
</jdbc:embedded-database>

让我们关注带有'int'名称空间的行:

网关的功能是将消息传递系统的管道与应用程序的其余部分分开。 这样,它就被业务逻辑隐藏了。 网关是双向的,因此您具有:

  • 入站网关:将消息带入应用程序并等待响应。
  • 出站网关:调用外部系统,并将响应发送回应用程序。

在此示例中,我们使用RMI入站网关。 它将通过RMI接收一条消息并将其发送到requestEmployee通道,该通道也在此处定义。

最后, 服务激活器允许您将spring bean连接到消息通道。 在这里,它连接到requestEmployee通道。 该消息将到达通道,服务激活器将调用retrieveEmployee方法。 考虑到如果bean只有一个公共方法或带有@ServiceActivator注释的方法,则不需要'method'属性。

然后,响应将发送到回复通道。 由于我们没有定义此通道,因此它将创建一个临时答复通道。

临时频道

3,实施客户

我们将要实现的客户端将调用服务以检索员工。 为此,它将使用MessagingTemplate类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:xpadro/spring/integration/test/config/client-config.xml"})
public class TestRmiClient {
    @Autowired
    MessageChannel localChannel;

    @Autowired
    MessagingTemplate template;

    @Test
    public void retrieveExistingEmployee() {
        Employee employee = (Employee) template.convertSendAndReceive(localChannel, 2);

        Assert.assertNotNull(employee);
        Assert.assertEquals(2, employee.getId());
        Assert.assertEquals("Bruce Springsteen", employee.getName());
    }
}

客户端使用messagingTemplate将Integer对象转换为Message并将其发送到本地通道。 如下所示,有一个出站网关连接到本地通道。 该出站网关将通过RMI发送请求消息。

<int-rmi:outbound-gateway request-channel="localChannel" remote-channel="requestEmployee" host="localhost"/>

<int:channel id="localChannel"/>

<bean class="org.springframework.integration.core.MessagingTemplate" />

4,抽象SI逻辑

在上一节中,您可能已经注意到,访问服务的客户端类具有特定于Spring Integration的逻辑及其业务代码:

  • 它使用MessagingTemplate,它是一个SI类。
  • 它了解本地通道,该本地通道特定于消息传递系统

在本节中,我将实现抽象邮件消息逻辑的相同示例,因此客户端将只关心其业务逻辑。

首先,让我们看一下新客户端:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:xpadro/spring/integration/test/config/client-gateway-config.xml"})
public class TestRmiGatewayClient {
    @Autowired
    private EmployeeService service;

    @Test
    public void retrieveExistingEmployee() {
        Employee employee = service.retrieveEmployee(2);

        Assert.assertNotNull(employee);
        Assert.assertEquals(2, employee.getId());
        Assert.assertEquals("Bruce Springsteen", employee.getName());
    }
}

现在我们可以看到,客户端仅实现其业务逻辑,而不使用消息通道或消息传递模板。 它只会调用服务接口。 所有消息传递定义都在配置文件中。

<int-rmi:outbound-gateway request-channel="localChannel" remote-channel="requestEmployee" host="localhost"/>

<int:channel id="localChannel"/>

<int:gateway default-request-channel="localChannel" 
    service-interface="xpadro.spring.integration.service.EmployeeService"/>

客户端网关配置文件

我们在这里所做的是添加一个网关,该网关将拦截对服务接口EmployeeService的调用。 Spring Integration将使用GatewayProxyFactoryBean类在服务接口周围创建代理。 该代理将使用消息传递模板将调用发送到请求通道并等待响应。

gatewayProxyFactoryBean

5,结论

我们已经看到了如何使用Spring Integration通过RMI访问服务。 我们还看到,我们不仅可以使用MessagingTemplate显式发送消息,还可以使用GatewayProxyFactoryBean透明地发送消息。


翻译自: https://www.javacodegeeks.com/2014/02/spring-integration-using-rmi-channel-adapters.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值