enricher 如何适配服务激活器和网关接口?

How enricher adapts the service activator and gateway interfaces?

我的问题基于官方样本:Spring Integration - Enricher Sample 让我们考虑以下 xml 配置:

<int:gateway id="userGateway" default-request-timeout="5000"
                 default-reply-timeout="5000"
                 service-interface="org.springframework.integration.samples.enricher.service.UserService">
        <int:method name="findUserWithUsernameInMap" request-channel="findUserWithMapEnricherChannel"/>
</int:gateway>
<int:enricher id="findUserWithMapEnricher"
                  input-channel="findUserWithMapEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="user"    expression="payload"/>
    </int:enricher>

<int:service-activator id="findUserByUsernameServiceActivator"
                           ref="systemService" method="findUserByUsername"
                           input-channel="findUserByUsernameServiceChannel"/>

SystemService 是:

public class SystemService {

    public User findUserByUsername(String username) {
            ...    
    }

}

UserService 是:

public interface UserService {

    Map<String, Object> findUserWithUsernameInMap(Map<String, Object> userdata);

}

所以我们有 3 个组成部分:

userGateway <---> enricher <---> findUserByUsernameServiceActivator

如您所见,UserService#findUserWithUsernameInMap 接受 Map<String, Object>SystemService#findUserByUsername 接受字符串。所以我们必须将 Map 转换为字符串。看起来像:

<request-payload-expression="payload.username">

对此负责。

此外 SystemService#findUserByUsername returns UserUserService#findUserWithUsernameInMap returns Map<String, Object> 但我没有看到任何地方发生这种转变.

所以我的问题是 User -> Map 转换是在哪里定义的?

我没有注意到一件重要的事情:UserService 的参数类型和 return 类型相同。所以我们将一些 ObjArg 传递给 enricher,然后它可以选择从 ObjArg 中提取一些数据并将其传递给 SystemService。当 SystemService returns someResult 时,我们基于 someResult 丰富 ObjArg。所以我们用 username 键传递了地图,并得到了带有 2 个键的地图:usernameuser

我找到了答案here

此配置:

<int:enricher id="findUserWithMapEnricher"
              input-channel="findUserWithMapEnricherChannel"
              request-channel="findUserByUsernameServiceChannel"
              request-payload-expression="payload.username">
    <int:property name="user"    expression="payload"/>
</int:enricher>

可以这样解释:

  1. findUserWithMapEnricherChannel 将消息作为 Map 传递给此组件。
  2. request-payload-expression="payload.username" 通过 username 键从地图中获取一个值。
  3. 这个普通的 username 值被发送到 findUserByUsernameServiceChannel
  4. 该频道上的服务return是User结果
  5. 表达式<int:property name="user" expression="payload"/>的意思是:在请求Map中添加一个新的user条目,并存储在findUserByUsernameServiceChannel[=38上调用服务的全部结果=]

因此在回复中发送了一个原始 Map,但已经有了一个新的 user 条目。 这是 enricher 的要点:在传入的 payload 中添加一些新内容(或修改),然后 return 返回。