覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

MBassador - サブクラスのメッセージ受信時の動き

MBassadorを用いてメッセージのハンドリングを行う場合のメッセージのサブクラスに対する動きを確認します。


本エントリでは、MessageObj とその子クラスの SubMessageObj を定義しました。これらをEventBusにpublishします。

■メッセージクラスの定義

public class MessageObj {

    protected final String rawMsg;

    public MessageObj(String rawMsg) {
        this.rawMsg = rawMsg;
    }

    String message() {
        return "MessageObj -> " + rawMsg;
    }
}
public class SubMessageObj extends MessageObj {

    public SubMessageObj(String rawMsg) {
        super(rawMsg);
    }

    @Override
    public String message() {
        return "MessageImpl -> " + rawMsg;
    }
}


デフォルトでのサブクラスのメッセージ受信時の動き

■Handlerの定義

MessageObjを引数に取るhandle1とSubMessageObjを引数に取るhandle2を定義しました

import net.engio.mbassy.listener.Handler;

class MessageObjListener {

    @Handler
    public void handle1(MessageObj msg){
        System.out.println("handle [MessageObj]: " + msg.message());
    }

    @Handler
    public void handle2(SubMessageObj msg){
        System.out.println("handle [SubMessageObj]: " + msg.message());
    }
}


■EventBusを作成してメッセージ送信

EventBusに上で定義したハンドラをセットしてMessageObjSubMessageObjのインスタンスを送信し動きを確認します

import net.engio.mbassy.bus.MBassador;


public class Main {

    public static void main(String[] args) {
        MBassador<Object> bus = new MBassador<>();
        bus.subscribe(new MessageObjListener());

        bus.publishAsync(new MessageObj("Hello World! - 1"));
        bus.publishAsync(new MessageObj("Hello World! - 2"));
        bus.publishAsync(new SubMessageObj("Hello World! - 1000"));
        bus.publishAsync(new SubMessageObj("Hello World! - 2000"));

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("\n>>> App end");
    }
}


■実行結果

handle [MessageObj]: MessageObj -> Hello World! - 1
handle [MessageObj]: MessageObj -> Hello World! - 2
handle [SubMessageObj]: SubMessageObj -> Hello World! - 1000
handle [MessageObj]: SubMessageObj -> Hello World! - 1000
handle [SubMessageObj]: SubMessageObj -> Hello World! - 2000
handle [MessageObj]: SubMessageObj -> Hello World! - 2000

>>> App end

MessageObjListener#handle1の引数はMessageObjですが、MessageObjおよびその子クラスのSubMessageObjも受け取っていることが分かります。


サブクラスのメッセージ受信しないようにする

場合によってはサブクラスのメッセージを受信したくない場合もあります。その場合は@HandlerアノテーションのrejectSubtypesパラメータを利用します

■Handlerの定義

ハンドラとして扱うメソッドに@Handlerを付与するとともにrejectSubtypesパラメータにtrueを指定します。これで引数のサブクラスのメッセージが受信しなくなります。

import net.engio.mbassy.listener.Handler;

class MessageObjListener {

    @Handler(rejectSubtypes = true)
    public void handle1(MessageObj msg){
        System.out.println("handle [MessageObj]: " + msg.message());
    }

    @Handler
    public void handle2(SubMessageObj msg){
        System.out.println("handle [SubMessageObj]: " + msg.message());
    }
}


■EventBusを作成してメッセージ送信

EventBusに上で定義したハンドラをセットしてMessageObjSubMessageObjのインスタンスを送信し動きを確認します

import net.engio.mbassy.bus.MBassador;


public class Main {

    public static void main(String[] args) {
        MBassador<Object> bus = new MBassador<>();
        bus.subscribe(new MessageObjListener());

        bus.publishAsync(new MessageObj("Hello World! - 1"));
        bus.publishAsync(new MessageObj("Hello World! - 2"));
        bus.publishAsync(new SubMessageObj("Hello World! - 1000"));
        bus.publishAsync(new SubMessageObj("Hello World! - 2000"));

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("\n>>> App end");
    }
}


■実行結果

handle [MessageObj]: MessageObj -> Hello World! - 1
handle [MessageObj]: MessageObj -> Hello World! - 2
handle [SubMessageObj]: SubMessageObj -> Hello World! - 1000
handle [SubMessageObj]: SubMessageObj -> Hello World! - 2000

>>> App end

MessageObjListener#handle1MessageObjのメッセージだけ受け取り、その子クラスのSubMessageObjのメッセージを受信しなくなっていることが分かります。



関連エントリ