我是Spring Integration的新手,我正在试验一个小项目中的各种组件。
在手头的任务中,我需要处理一个文本文件并将其内容存储到数据库中。该文件包含可以组合在一起的行,因此将每个文件分成几个独立的消息是很自然的。
这是整个过程(请参见最后的配置):
transformers.outcomeTransf
splitters.outcomeSplit
transformers.SingleoutcomeToMap
stored-proc-outbound-channel-adapter
数据库只包含两个表:
我缺少第2步的组件。据我所知,通道出站适配器“吞下”它处理的消息,因此没有其他端点可以接收它。
在第一步之后我想到了一个发布 - 订阅频道(没有TaskExecutor
),其中 jdbc出站适配器作为第一个订阅者和来自的分离器第3个作为第二个:每个订阅的处理程序应该接收消息的副本,但是我不清楚分割器中的任何处理是否会等待出站适配器完成。
这是完成任务的正确方法吗?如果步骤4中的变换器被异步调用怎么办 - 每个分裂的消息都是自包含的,并且会调用并发性。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/jdbc
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- input-files-from-folder -->
<int-file:inbound-channel-adapter id="outcomeIn"
directory="file:/in-outcome">
<int:poller id="poller" fixed-delay="2500" />
</int-file:inbound-channel-adapter>
<int:transformer input-channel="outcomeIn" output-channel="outcomesChannel" method="transform">
<beans:bean class="transformers.outcomeTransf" />
</int:transformer>
<!-- save source to db! -->
<int:splitter input-channel="outcomesChannel" output-channel="singleoutcomeChannel" method="splitMessage">
<beans:bean class="splitters.outcomeSplit" />
</int:splitter>
<int:transformer input-channel="singleoutcomeChannel" output-channel="jdbcChannel" method="transform">
<beans:bean class="transformers.SingleoutcomeToMap" />
</int:transformer>
<int-jdbc:stored-proc-outbound-channel-adapter
data-source="dataSource" channel="jdbcChannel" stored-procedure-name="insert_outcome"
ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definitions ... />
<int-jdbc:parameter ... />
</int-jdbc:stored-proc-outbound-channel-adapter>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="org.postgresql.Driver"/>
<property ... />
</bean>
</beans>
答案 0 :(得分:1)
你认为正确的方法。如果您的PublishSubscribeChannel
没有Executor
,则每个下一个订阅者将在上一个完成其工作时等待。因此,在DB上完成所有操作之前,不会调用spllitter
。默认情况下,当第一个订户无法处理消息(而不是数据库连接?)时,所有其他用户都不会被呼叫。
可以使用<request-handler-advice-chain>
和ExpressionEvaluatingRequestHandlerAdvice
配置另一种实现类似行为的方式:https://docs.spring.io/spring-integration/docs/5.0.4.RELEASE/reference/html/messaging-endpoints-chapter.html#expression-advice
所有拆分器下游流并发和多线程已经与DB逻辑无关。在DB正确执行请求之前,并行性不会发生。