如何使用 spring integraton java DSL 实现丰富器? [英] How to implement enricher using spring integraton java DSL?

查看:28
本文介绍了如何使用 spring integraton java DSL 实现丰富器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想重写以下 xml 示例 使用 java DSL

I want to rewrite following xml sample using java DSL

xml 配置:

    <int:channel id="findUserServiceChannel"/>
    <int:channel id="findUserByUsernameServiceChannel"/>

    <!-- See also:
        https://docs.spring.io/spring-integration/reference/htmlsingle/#gateway-proxy
        https://www.enterpriseintegrationpatterns.com/MessagingGateway.html -->
    <int:gateway id="userGateway" default-request-timeout="5000"
                 default-reply-timeout="5000"
                 service-interface="org.springframework.integration.samples.enricher.service.UserService">
        <int:method name="findUser"                  request-channel="findUserEnricherChannel"/>
        <int:method name="findUserByUsername"        request-channel="findUserByUsernameEnricherChannel"/>
        <int:method name="findUserWithUsernameInMap" request-channel="findUserWithMapEnricherChannel"/>
    </int:gateway>

    <int:enricher id="findUserEnricher"
                  input-channel="findUserEnricherChannel"
                  request-channel="findUserServiceChannel">
        <int:property name="email"    expression="payload.email"/>
        <int:property name="password" expression="payload.password"/>
    </int:enricher>

    <int:enricher id="findUserByUsernameEnricher"
                  input-channel="findUserByUsernameEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="email"    expression="payload.email"/>
        <int:property name="password" expression="payload.password"/>
    </int:enricher>

    <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="findUserServiceActivator"
                           ref="systemService" method="findUser"
                           input-channel="findUserServiceChannel"/>

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

    <bean id="systemService"
          class="org.springframework.integration.samples.enricher.service.impl.SystemService"/>

现在我有以下几点:

配置:

@Configuration
@EnableIntegration
@IntegrationComponentScan
public class Config {

    @Bean
    public SystemService systemService() {
        return new SystemService();
    }

    @Bean
    public IntegrationFlow findUserEnricherFlow(SystemService systemService) {
        return IntegrationFlows.from("findUserEnricherChannel")
                .<User>handle((p, h) -> systemService.findUser(p))
                .get();
    }

    @Bean
    public IntegrationFlow findUserByUsernameEnricherFlow(SystemService systemService) {
        return IntegrationFlows.from("findUserByUsernameEnricherChannel")
                .<User>handle((p, h) -> systemService.findUserByUsername(p.getUsername()))
                .get();
    }

    @Bean
    public IntegrationFlow findUserWithUsernameInMapFlow(SystemService systemService) {
        return IntegrationFlows.from("findUserWithMapEnricherChannel")
                .<Map<String, Object>>handle((p, h) -> {
                    User user = systemService.findUserByUsername((String) p.get("username"));
                    Map<String, Object> map = new HashMap<>();
                    map.put("username", user.getUsername());
                    map.put("email", user.getEmail());
                    map.put("password", user.getPassword());
                    return map;
                })
                .get();
}
}

服务接口:

@MessagingGateway
public interface UserService {

    /**
     * Retrieves a user based on the provided user. User object is routed to the
     * "findUserEnricherChannel" channel.
     */
    @Gateway(requestChannel = "findUserEnricherChannel")
    User findUser(User user);

    /**
     * Retrieves a user based on the provided user. User object is routed to the
     * "findUserByUsernameEnricherChannel" channel.
     */
    @Gateway(requestChannel = "findUserByUsernameEnricherChannel")
    User findUserByUsername(User user);

    /**
     * Retrieves a user based on the provided username that is provided as a Map
     * entry using the mapkey 'username'. Map object is routed to the
     * "findUserWithMapChannel" channel.
     */
    @Gateway(requestChannel = "findUserWithMapEnricherChannel")
    Map<String, Object> findUserWithUsernameInMap(Map<String, Object> userdata);

}

目标服务:

public class SystemService {

    public User findUser(User user) {
            ...
    }

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

}

主要方法:

public static void main(String[] args) {
    ConfigurableApplicationContext ctx = new SpringApplication(MyApplication.class).run(args);
    UserService userService = ctx.getBean(UserService.class);
    User user = new User("some_name", null, null);
    System.out.println("Main:" + userService.findUser(user));
    System.out.println("Main:" + userService.findUserByUsername(user));
    Map<String, Object> map = new HashMap<>();
    map.put("username", "vasya");
    System.out.println("Main:" + userService.findUserWithUsernameInMap(map));
}

输出:

2019-08-30 14:09:29.956  INFO 12392 --- [           main] enricher.MyApplication                   : Started MyApplication in 2.614 seconds (JVM running for 3.826)
2019-08-30 14:09:29.966  INFO 12392 --- [           main] enricher.SystemService                   : Calling method 'findUser' with parameter User{username='some_name', password='null', email='null'}
Main:User{username='some_name', password='secret', email='some_name@springintegration.org'}
2019-08-30 14:09:29.967  INFO 12392 --- [           main] enricher.SystemService                   : Calling method 'findUserByUsername' with parameter: some_name
Main:User{username='some_name', password='secret', email='some_name@springintegration.org'}
2019-08-30 14:09:29.967  INFO 12392 --- [           main] enricher.SystemService                   : Calling method 'findUserByUsername' with parameter: vasya
Main:{password=secret, email=vasya@springintegration.org, username=vasya}

如您所见,一切正常,但我在配置中进行了转换.我不确定是否必须这样做,因为 xml 配置没有这样的转换,而且一切都以某种方式使用内部魔法工作.这是正确的方法还是我应该使用一些内部 DSL 魔法进行转换?

As you can see everything is working properly but I do transformations inside the configuration. I am not sure if I have to do it because xml configuration dooesn't have such transformations and everything somehow works using internal magic. Is it correct way or should I use some internal DSL magic for transformations?

我想可以以某种方式简化 Config 类.我的意思是 findUserByUsernameEnricherFlow findUserWithUsernameInMapFlow 方法

I suppose that Config class can be simplified somehow. I mean findUserByUsernameEnricherFlow findUserWithUsernameInMapFlow methods

我意识到我并不真正了解 XML 配置的工作原理:

I realized that I don't really understand how the XML config works:

让我们考虑方法 Userservice#findUserWithUsernameInMap 方法

Let's consider method Userservice#findUserWithUsernameInMap method

它有如下界面:

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

并最终调用SystemServicefindUserByUsername方法:

public User findUserByUsername(String username) 

因为客户端代码与 Userservice 一起工作,所以内部有 2 个转换:

Because client code work with Userservice there are 2 transformations inside:

  1. on way TO(在 SystemService#findUserByUsername 调用之前)因为 Userservice#findUserWithUsernameInMap 接受 MapSystemService#findUserByUsername 接受字符串

  1. on way TO (before SystemService#findUserByUsername invocation) because Userservice#findUserWithUsernameInMapaccept Map<String, Object> but SystemService#findUserByUsername accepts String

返回途中(在SystemService#findUserByUsername 调用之后)因为SystemService#findUserByUsername 返回 User 但Userservice#findUserWithUsernameInMap 返回映射<字符串、对象>

On way BACK(afterSystemService#findUserByUsername invocation) because SystemService#findUserByUsernamereturns User but Userservice#findUserWithUsernameInMap returns Map<String, Object>

这些转换在 xml 配置中具体在哪里声明?

Where exactly these transformations are declared in the xml configuration?

我建议 request-payload-expression 用于进行 TO 转换.看起来它可以使用与 Object 相同的方式与 Map 一起使用.但是 BACK 变换完全不清楚.确定配置有

I have a suggestion that request-payload-expression is ised to make TO tranformation. Looks like it can work with Map using the same manner as with Object. But BACK transformation is not clear at all. Sure configiration has

<int:property name="user"    expression="payload"/>

但我不知道这是什么意思.

But I have no idea what does it mean.

推荐答案

的 Java DSL 等价物是 .enrich().所以,你的 findUserEnricherFlow 应该是这样的:

The Java DSL equivalent of the <int:enricher> is .enrich(). so, your findUserEnricherFlow should be like this:

@Bean
public IntegrationFlow findUserEnricherFlow(SystemService systemService) {
    return IntegrationFlows.from("findUserEnricherChannel")
            .enrich((enricher) -> enricher
                         .requestChannel("findUserServiceChannel")
                         .propertyExpression("email", "payload.email")
                         .propertyExpression("password", "payload.password"))

            .get();
}

您仍然可以简单地将您的问题指向一种网关方法和一种浓缩器...

You still could simply your question pointing only to one gateway method and one enricher...

这篇关于如何使用 spring integraton java DSL 实现丰富器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆