我需要将一些遗留代码移植到基于Spring集成的应用程序中。我决定通过@InboundChannelAdapter
注释配置入站通道适配器,该注释按预期工作。
问题是,当调用入站通道适配器的start()
和stop()
方法时,我需要执行一些代码。
我尝试通过实现SmartLifecycle
接口来解决这个问题,但这并没有让我感到满意。有没有人有任何其他建议我应该尝试?我现在卡住了...
编辑:代码示例
@MessageEndpoint
@Component
public class InputSource implements SmartLifecycle {
public void start() {
//my code to be executed
}
public void stop() {
//my code
}
@InboundChannelAdapter("some.channel")
public Message<?> read() {
//my code that returns a message
}
}
启动入站通道适配器时会调用read()
方法中的代码,但在创建上下文时不会调用start()
。
答案 0 :(得分:1)
什么版本的Spring Integration?对于4.1.0 ...
,这对我来说很好@EnableIntegration
@MessageEndpoint
@Component
public class InputSource implements SmartLifecycle {
private boolean running;
@Override
public void start() {
System.out.println("start");
running = true;
}
@Override
public void stop() {
running = false;
}
@InboundChannelAdapter(value = "toRabbit", poller = @Poller(fixedDelay = "5000", maxMessagesPerPoll = "1"))
public Message<?> read() {
return new GenericMessage<String>("foo");
}
@Override
public boolean isRunning() {
return running;
}
@Override
public int getPhase() {
return 0;
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
stop();
callback.run();
}
}
(即使没有@EnableIntegration
调用start()
方法也是如此。
在任何情况下,请记住这里的开始/停止位于不同的bean(InputSource
)上,而适配器上的开始/停止位于SourcePollingChannelAdapter
上。您可以使用phase
控制订单。
修改强>
根据您的评论,您希望适配器启动其来源。即使我们这样做了......
if (this.source implements Lifecycle) {
((Lifecycle) source).start();
}
...它在这里不起作用,因为源不是你的组件,它是MethodInvokingMessageSource
,它对bean的其余部分一无所知,只是read()
方法。
一个解决方法是继承SourcePollingChannelAdapter
并覆盖它的doStart()方法......
@Override // guarded by super#lifecycleLock
protected void doStart() {
myInputSource.start();
super.doStart();
}
您必须手动连接此(和您的bean)。可能最容易做的就是使用InputSource
工具MessageSource
...
@Component
public class InputSource implements MessageSource<String>, Lifecycle {
private boolean running;
@Override
public void start() {
System.out.println("start");
running = true;
}
@Override
public void stop() {
running = false;
}
@Override
public Message<String> receive() {
return new GenericMessage<String>("foo");
}
@Override
public boolean isRunning() {
return running;
}
}
并将其与投票信息一起发送到MySPCA
。
我创建了一个Improvement JIRA Issue来支持这个用例。
谢谢!