5

Spring Bean の init-method でチャネルにメッセージを投稿しようとすると、「Dispatcher has nosubscribes」エラーが発生する。以下の例を見てください。

applicationContext.xml

<?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:p="http://www.springframework.org/schema/p"
    xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
    xmlns:int="http://www.springframework.org/schema/integration"
    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/rmi
        http://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd">

    <bean id="currencyService" class="com.demo.CurrencyService" init-method="init"/>

    <int:channel id="currencyChannel" />
    <int:channel id="currencyReplyChannel">
        <int:queue/>
    </int:channel>
    <rmi:outbound-gateway id="currencyServiceGateway"
        request-channel="currencyChannel" remote-channel="currencyServiceChannel"
        reply-channel="currencyReplyChannel" host="localhost" port="2197" />
</beans>

スプリングマネージドビーン:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.message.GenericMessage;

public class CurrencyService {

    @Autowired
    private MessageChannel currencyChannel;

    @Autowired
    private PollableChannel currencyReplyChannel;

    private CurrencyListBO currencyListBO;

    public CurrencyListBO getCurrencyList() {
        return currencyListBO;
    }

    public void init() {
        CurrencyIN request = new CurrencyIN();
        request.setChannelCode("RMW");
        request.setTransactionType(CurrencyIN.TransactionType.currencyLoaderService
                .toString());
        GenericMessage<IRequestBO> message = new GenericMessage<IRequestBO>(
                request);
        MessagingTemplate template = new MessagingTemplate();
        template.send(currencyChannel, message);
        Message<CurrencyListBO> reply = template.receive(currencyReplyChannel);
        currencyListBO = reply.getPayload();
    }
}

init-method の代わりに currencyListBO が最初の呼び出し後に初期化された場合、すべて正常に動作します。

public CurrencyListBO getCurrencyList() {
    if(currencyListBO == null) {
        init();
    }
    return currencyListBO;
}

最初のアプローチの問題点を教えてください。

4

1 に答える 1

7

init / @ PostConstructメソッドは、Beanがインスタンス化された後、残りのコンテキストが接続される前(この場合、RMIアダプターがチャネルにサブスクライブされる前)に呼び出されます。

コンテキストが完全に更新されるまで待つ必要があります。

そのための1つの方法は、実装することです

ApplicationListener<ContextRefreshedEvent>

コードを入れます

public void onApplicationEvent(ContextRefreshedEvent event)

そのメソッドは、コンテキストが完全に配線された後に呼び出されます。

于 2012-06-21T11:49:11.637 に答える