【问题标题】:Spring Integration Annotations and the SmartLifecycle interfaceSpring 集成注解和 SmartLifecycle 接口
【发布时间】:2015-01-29 15:52:36
【问题描述】:

我有一些遗留代码需要移植到基于 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() 在创建上下文时不会被调用。

【问题讨论】:

  • 你能展示一些配置吗?
  • 用一个例子编辑

标签: java spring spring-integration


【解决方案1】:

什么版本的 Spring 集成?这对我来说很好用 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控制订单。

编辑:

根据下面的 cmets,您希望适配器启动其源。即使我们这样做了......

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 来支持这个用例。

谢谢!

【讨论】:

  • 例如,当通过 jmx 调用时,我希望让适配器的 start() 调用 InputSource.start()
  • 就像我说的 - 它是一个不同的 bean - 它不是适配器;这是一个名为 inputSource 的 bean。
  • 但是我想要做的甚至可行吗?
  • 哦,这就是 spring 集成 4.0.4.RELEASE
  • 感谢您的宝贵时间!我一定会这样做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
相关资源
最近更新 更多