1

Spring Framework (3.2.3.RELEASE) を使用して物事を結び付ける TCP Socket Server を構築しています。

Java Config with Annotations を使用してすべてが設定されます。Java Config には@ComponentScan、クラスパス内のコンポーネントをスキャンするための注釈があります。

メッセージが TCP ソケット サーバーによって受信されたときに、いくつかのイベントをディスパッチしたいことがあります。これには、Google Guice EventBus を使用します。TCP Socket Server にイベント レシーバーを認識させたくないし、その逆も同様です。物事を疎結合に保つためです。

EventBusRegisterBeanPostProcessorPatrick Meade @ http://pmeade.blogspot.no/2013/02/using-guava-eventbus-with-spring-part-2.htmlから提供されたコードから登録しました

これにより、任意の Bean がスキャンされ、EventBus に登録されます。

イベントをリッスン (サブスクライブ) するには、次のような POJO を作成するだけです。

@Component
public class PingMessageReceivedHandler {

    static Logger logger = Logger.getLogger(PingMessageReceivedHandler.class);

    @Subscribe
    public void handleMessageReceivedEvent(MessageReceivedEvent messageReceivedEvent) {
        logger.info(messageReceivedEvent.getMessage());
        messageReceivedEvent.getChannel().writeAndFlush(new BaseMessage(false, "Pong", null, ""));
    }

}

さて、問題は次のとおりです。私が別のサービスやコンポーネントなどのどこかに依存関係を置かない限りPingMessageReceivedHandler(たとえば を使用して@Autowired)、 はEventBusRegisterBeanPostProcessorを認識せず、PingMessageReceivedHandlerメッセージをディスパッチしません。

PingMessageReceivedHandlerログの状態として、Spring はの存在を認識していることを知っています。

2013-11-04 17:35:05,391  INFO [main] (DefaultListableBeanFactory.java:596) - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9695ed7: defining beans [[...],pingMessageReceivedHandler,[...],eventBusRegisterBeanPostProcessor]; root of factory hierarchy

これを引き起こしている原因についてのアイデアはありますか?さらに重要なことに、どうすれば修正できますか?

編集: コンテキスト構成:

@ComponentScan(value = "com.company.product")
@Configuration
public class DeviceManagerServerConfig {

    @Bean
    public static EventBusRegisterBeanPostProcessor eventBusRegisterBeanPostProcessor() {
        return new EventBusRegisterBeanPostProcessor();
    }

    @Bean
    public EventBus eventBus() {
        return new EventBus("standard");
    }
}

以下を使用して初期化されます。

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DeviceManagerServerConfig.class);
context.refresh();
4

2 に答える 2

0

問題は、ブロッキング操作 (TCP ソケット サーバー) を持つ Bean を初期化しようとしたことです。

これにより、Spring がさらに Bean を初期化できなくなり、元の投稿で問題が発生しました。

すなわち:

@Component
@Profile("default")
public class SocketServerImpl implements SocketServer {
    /**
    * Instantiates a new socket server.
    */
    public SocketServerImpl() {
        /* Standard stuff */
    }


    @PostConstruct
    @Override
    public void start() {
        /* This would block any further progressing */
    }
}

私の修正は非常に簡単で、@PostConstruct上記のコードから削除し、public static void mainを呼び出した後context.refresh()、 を呼び出しcontext.getBean(SocketServer.class).start()ました。

于 2013-11-04T23:03:12.763 に答える
-1

追加してみる

@Lazy(false)

ハンドラー Bean に。

どういうわけかデフォルトで怠惰と宣言されているため、依存関係なしでは起動時にロードされないと思います。

于 2013-11-04T17:01:46.643 に答える