2014-12-01 3 views
2

У меня есть код устаревшего кода, который мне нужно передать в приложение для интеграции с пружиной. Я решил настроить входящие адаптеры каналов через аннотацию @InboundChannelAdapter, которая работает так, как ожидалось.Аннотации для интеграции Spring и интерфейс SmartLifecycle

Проблема заключается в том, что у меня есть код, который необходимо выполнить, когда вызываются методыи stop() адаптера входящего канала.

Я попытался сделать это с помощью интерфейса SmartLifecycle, но это меня никуда не доставило. Есть ли у кого-нибудь другие предложения, которые я должен попробовать? Я вроде застрял прямо сейчас ...

Edit: пример кода

@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

Можете ли вы показать какую-то конфигурацию? –

+0

Отредактировано с помощью примера –

ответ

1

Какая версия весенней интеграции? Это отлично работает для меня с 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() называется).

В любом случае, помните, что начало/остановка находится на другом боне (InputSource), тогда как начало/остановка на адаптере находится на его SourcePollingChannelAdapter. Вы можете управлять заказом с помощью phase.

EDIT:

на основе ваших комментариев ниже вы хотите адаптер, чтобы начать свой источник. Даже если бы мы сделали это ...

if (this.source implements Lifecycle) { 
    ((Lifecycle) source).start(); 
} 

... он не будет работать здесь, потому что источник не ваш компонент, это MethodInvokingMessageSource, что ничего не знает об остальной фасоли, только методом read().

Одна работа вокруг будет подкласс SourcePollingChannelAdapter и переопределить его метод doStart() ...

@Override // guarded by super#lifecycleLock 
protected void doStart() { 
    myInputSource.start(); 
    super.doStart(); 
} 

Вы должны подключить этот (и ваш боб) вручную. Наверное, проще всего сделать, это ваш 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 для поддержки этого прецедента.

Спасибо!

+0

Я ищу, чтобы получить «start()' адаптера для вызова 'InputSource.start()' при вызове через jmx, например. –

+0

Как я уже сказал - это разные бобы - это не адаптер; это bean, называемый 'inputSource'. –

+0

Но это то, что я хочу сделать даже выполнимо? –

Смежные вопросы