大きく変わって使いやすくなったVert.x 3.0
6月22日に公開されたばかりなのでまだ深くは踏み込めていませんが、v2.1系からはほぼすべてが変わったと言っても過言ではないくらい大幅に変更されています。
変更点についてはv2.1系からv3.0系へ移行するためのチェックリストの一部をVert.xのブログで公開してくれていますので、そちらを参照すると理解の一助になると思います。基本的にv2.1系で作成したものをそのままv3系で動かすことはできませんので、諦めて大幅なリファクタリングを行う必要があります。
分かりやすい変更点としては、まずパッケージ名がorg.vertxからio.vertxに変更されました。これだけでもまったく互換性がないことが分かるかと思います。
非常に変更が多いため、いくつか目立った箇所を挙げていきたいと思います。
Java 8が必須に
Java 8が前提になりました。Lambda式を活用することで以前よりもコードを短くすることが可能になっています。
Reactiveサポート
RxJavaが公式でサポートされ、ReactiveStreamsにも対応しました。
シンプルになったクラスローダー
第2回で記載したクラスローダーの仕組みはかなり特殊で分かりづらいものでした。v3.0系ではその点が見直されてシンプルな形に直されています。デフォルトでは通常のJavaアプリケーションと同様に共通のクラスローダーが使用されますが、オプションを指定("isolationGroup":"xxx")した場合のみ、独立したクラスローダーが使用されるようになりました。
インターフェースになったVerticle
v2.1系では基本となるorg.vertx.java.platform.Verticleがabstractクラスとして存在しましたが、今回はio.vertx.core.Verticleというインターフェースになっています。実際に実装クラスを作成する場合は、Javaの場合io.vertx.core.AbstractVerticleを継承します。
registerHandlerからConsumerに
EventBusに存在したregisterHandlerメソッドがなくなり、consumerメソッドでMessageConsumerインスタンスを取得後、handlerメソッドに登録する形式になりました。
JSON以外もメッセージにできるCodec定義
v2.1系までは各モジュール間のメッセージにJsonObjectなど非常に限定されたクラスしか使用できませんでした。v3.0系ではMessageCodecを作成することで任意の型を利用できる機能ができました。
io.vertx.core.eventbus.MessageCodecインターフェースを実装したクラスを作成し、EventBusのregisterDefaultCodec(Class<T> clazz, MessageCodec<T,?> codec) メソッドを使用して登録することで任意のクラスをメッセージにするための送受信用コーデッククラスを登録できます。
ただし、特定のClassと直接結びつける必要があるためClassごとに登録をしなければならず、冗長な記述を強いられることになります。
汎用的なCodecを使用したい場合にはClassで判定させるのではなく、DeliveryOptions.setCodecName メソッドを使用してコーデック名を指定してあげれば、送信時のCodecを変更することができます(ここのコーデック名とは、MessageCodec.nameメソッドで返す名前になります)。
毎回送信時にコーデック名を指定することにすれば各Classと結びつける必要はありませんので、その場合は registerCodec(MessageCodec<T,?> codec)を利用することでコーデック名を指定した時だけCodecが利用できるようになります。メッセージを受信するだけの場合にも、こちらのメソッドでCodecの登録が必要になります。
また、このMessageCodecは分散処理を行う際など、リモートプロセスにメッセージを送る場合にはすべてのメソッドの実装が必要ですが、単独プロセス内でしかメッセージを送りあわない場合には、encodeToWire、decodeFormWireというbyte変換を必要とするメソッドの実装は必要ありません。ただし、簡単な処理ではありますが、transformメソッド、nameメソッド、systemCodecIDメソッドの実装は必須になります。
HeaderのついたMessage
以前のMessageはヘッダー情報など付与できませんでしたが、v3.0のMessageではDeliveryOptions.addHeaderメソッド、setHeadersメソッドを使用することで、任意のヘッダー情報を付与することができます。これにより、各モジュールを横断するMessageに追跡情報などを付与しやすくなりました。
PluggableになったClusterManager
v2.1まではクラスタリングをHazelcastに依存していましたが、io.vertx.core.spi.cluster.ClusterManagerとしてインターフェースを独立させることで、任意に変更可能になりました。公式に記載されているものは相変わらずHazelcastのみですが、github上にはvertx-infinispanなども公開されており、状況により任意のライブラリを利用できるように変更が可能になりました。
その他にも
ServiceやMetricsなど簡単に紹介しきれないくらいの多くの機能が追加、変更されています。正直なところv2.1系までは癖が強くかなり使いづらい点も多くありましたが、今回のv3.0はより使いやすくなり、選択肢としての可能性があがったのではないでしょうか。
連載のまとめ
最終回となる今回は、DMMが実際にVert.xを使ってどのようなアプリケーションを開発したのかを簡単にご紹介し、また大幅に進化したv3.0の機能についても触り程度ですが、ご紹介してみました。
この連載を通してVert.xの仕組みや具体的なコーディングなどを例示してきましたが、新しいプロダクトの開発時に候補として少しでも魅力が伝われば幸いです。
現在、DMMではv3.0を使用した新たなアプリケーションの開発も進んでおります。またどこかの機会で詳しくご紹介できればと思います。
