java - Spring 集成注释和 SmartLifecycle 接口(interface)

标签 java spring spring-integration

我有一些遗留代码需要移植到基于 Spring 集成的应用程序中。我决定通过 @InboundChannelAdapter 注释配置入站 channel 适配器,它按预期工作。

问题是,当调用入站 channel 适配器的 start()stop() 方法时,我需要执行一些代码。

我尝试通过实现 SmartLifecycle 接口(interface)来实现这一点,但这并没有让我有任何进展。有人有其他我应该尝试的建议吗?我现在有点陷入困境......

编辑:代码示例

@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
    }

}

当我启动入站 channel 适配器时,read() 方法中的代码将被调用,但在创建上下文时,start() 不会被调用。

最佳答案

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支持此用例。

谢谢!

关于java - Spring 集成注释和 SmartLifecycle 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27231833/

相关文章:

spring-boot 自定义 Jetty SSLContextFactory

java - 响应客户端后如何提取有效负载?

java - 为什么此 Function<List<Person>,String> 不起作用?

java - Spring 框架处理图像文件的首选方式是什么?

java - ReflectionTestUtils.setfield 不会覆盖本地项目属性

spring-integration - 放在 void http-inbound-gateway 上

java - 使用错误的方法无法聚合消息?

java - SSLHandshakeErrorTracker : SSLC0008E: Unable to initialize SSL connection. 未经授权的访问被拒绝或安全设置已过期

java - Spring 4 @RequestMapping - 消耗 vs header ?

java - 错误 : Gradle: execution failed for task ':app:preDexDebug'