英語がさっぱりできないのにRich Client Programming PLUGGING INTO THE NETBEANS PLATFORMを買ってしまった。
とりあえず、NetBeansのモジュールのプログラムを覗いてると良く出てくるLookupについて。
Lookupの機能自体はすごく単純でjarを1つクラスパスに追加するだけで使えるようになるらしい。
そのjarとは、NB_HOME/platform7/lib/org-openide-util.jarらしい。
(NetBeans6の場合のパスです。NetBeans5系は多分platform6とかのはず)
Javaアプリケーションプロジェクト作成
とりあえず、さくっとお試しするためにJavaプリケーションのプロジェクトを作成。
ライブラリにorg-openide-util.jarを追加する。
Mainクラスに下のようなコードを書いて実行できることを確認!
package okazuki.lookup; import org.openide.util.Lookup; public class Main { public static void main(String[] args) { Lookup lookup = Lookup.getDefault(); System.out.println(lookup); } }
実行結果はこんな感じ。
ProxyLookup(class=class org.openide.util.Lookup$DefLookup)->[MetaInfServicesLookup[sun.misc.Launcher$AppClassLoader@a90653], SimpleLookup[sun.misc.Launcher$AppClassLoader@a90653]]
ちゃんと何か取れとるらしい。
そもそもLookupって?
何かしらんがオブジェクトが欲しいときに探してくれるっぽい。
たとえばLookupが中に持ってるオブジェクト全部ほしいときは下のようになる。
NetBeans6と、それ以前では書き方が違うみたいなので2通りかいてます。
package okazuki.lookup; import java.util.Collection; import org.openide.util.Lookup; public class Main { public static void main(String[] args) { Lookup lookup = Lookup.getDefault(); { // NetBeans6 Collection objs = lookup.lookupAll(Object.class); for (Object obj : objs) { System.out.println(obj); } } { //NetBeans5.x Lookup.Template template = new Lookup.Template(Object.class); Lookup.Result results = lookup.lookup(template); Collection objs = results.allInstances(); for (Object obj : objs) { System.out.println(obj); } } } }
実行するとこんな感じ。
sun.misc.Launcher$AppClassLoader@a90653 sun.misc.Launcher$AppClassLoader@a90653
どうやら1つしかオブジェクト持ってないらしい。
この中に俺様オブジェクトを追加するには、META-INF/services以下にファイルを置くとできるって書いてある。
その前に登録するためのクラスを定義!!
お決まりのハローワールドです
// Greeter.java package okazuki.lookup; public interface Greeter { void greet(); } -------------------------------- // GreeterImpl.java package okazuki.lookup; public class GreeterImpl implements Greeter { public void greet() { System.out.println("Hello world"); } }
ソースフォルダ以下にMETA-INF/services/okazuki.lookup.Greeterという名前のファイルを作る。
中身は下のとおり。
okazuki.lookup.GreeterImpl
そしてメインメソッドを下のように変更する。
取得するクラスをGreeterにしている。
package okazuki.lookup; import java.util.Collection; import org.openide.util.Lookup; public class Main { public static void main(String[] args) { Lookup lookup = Lookup.getDefault(); { // NetBeans6 Collection<? extends Greeter> objs = lookup.lookupAll(Greeter.class); for (Greeter obj : objs) { obj.greet(); } } { //NetBeans5.x Lookup.Template<Greeter> template = new Lookup.Template<Greeter>(Greeter.class); Lookup.Result<Greeter> results = lookup.lookup(template); Collection<? extends Greeter> objs = results.allInstances(); for (Greeter obj : objs) { obj.greet(); } } } }
実行するとちゃんとHello worldが出てる。
Hello world Hello world
んじゃ差し替えてみよう
GreeterImpl以外のファイルも付け加えてみよう。
たとえば、GreeterImpl2というクラスを作ったとする。
中身は下のとおり
package okazuki.lookup; public class GreeterImpl2 implements Greeter { public void greet() { System.out.println("こんにちは世界"); } }
そして、META-INF/services/okazuki.lookup.Greeterの中身にGreeterImpl2を付け加える
okazuki.lookup.GreeterImpl okazuki.lookup.GreeterImpl2
この状態でリビルドして実行すると…
Hello world こんにちは世界 Hello world こんにちは世界
おぉ〜!ちゃんと出た!!!
DIコンテナあたりを使うともっと高度な事ができるけど、そんな機能イラネってときには使えるかな?