如何使用 spring integraton java DSL 实现丰富器? [英] How to implement enricher using 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);
并最终调用SystemService
的findUserByUsername
方法:
public User findUserByUsername(String username)
因为客户端代码与 Userservice
一起工作,所以内部有 2 个转换:
Because client code work with Userservice
there are 2 transformations inside:
on way TO(在
SystemService#findUserByUsername
调用之前)因为Userservice#findUserWithUsernameInMap
接受Map
但SystemService#findUserByUsername
接受字符串
on way TO (before
SystemService#findUserByUsername
invocation) becauseUserservice#findUserWithUsernameInMap
acceptMap<String, Object>
butSystemService#findUserByUsername
accepts String
返回途中(在SystemService#findUserByUsername
调用之后)因为SystemService#findUserByUsername
返回 User 但Userservice#findUserWithUsernameInMap
返回映射<字符串、对象>
On way BACK(afterSystemService#findUserByUsername
invocation) because SystemService#findUserByUsername
returns 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屋!