Java EE6の開発をしていて、「自分がやっていることは正しいのか…」と悩み、迷うことがあります。
わかりやすく自分が実際に迷った道を書いてみます。
Javaでコールバックを実装したいなー、と思って以下のサイト情報を見つけました。
Java コールバック関数
わかりやすい(^^)
ちなみに、いきなり脱線ですがJavaのコールバックの情報
やはり上記サイトのようにインタフェース利用するのがメジャーなんですかね。
アノテーション使う例もあるようです。
で、本題ですが、先のサイトではMain関数があって、Java SEでのサンプルコードとなっています。
じゃあ、Java EEになると…?と一瞬止まりますが、まあここは何とかなります。
サイトのソースをそのままに、Mainクラスだけを書き換えると多分こんな感じかと↓
package jp.co.hoge.bean;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import jp.co.hoge.callback.A;
import jp.co.hoge.callback.B;
import jp.co.hoge.callback.MyInterface;
@Named(value = "main")
@RequestScoped
public class MainBean implements Serializable{
@Inject
A a;
@Inject
B b;
public MainBean(){
}
public void btnClick(){
testCallback(a);
testCallback(b);
}
private void testCallback(MyInterface myinterface){
myinterface.doit();
}
}
上記はCDI管理対象Beanを利用してます。
ここで既に違ってたら恥ずかしい…ですが…。
で、main関数の代わりに、ボタンが押されたらコールバック処理を各々呼ぶ、みたいな記述にしてます。
上記の単純な例は普通に書けるのがわかりました。
でも実際には、クラスAやクラスBの中身では、EJBを呼び出したりとか、色々したいわけです。
例えば以下のような単純なEJBを用意します。
package jp.co.hoge.business;
import javax.ejb.Stateless;
@Stateless
public class SomethingEjb {
public String callEjb(){
return "EJBの実装だよ";
}
}
現実的にはDB処理とかになりますが、例を簡単にするために上記の定義とします。
POJOからEJBを呼ぶ…?
で、自分の場合、ここら辺で「ふにゃ?」となります。
以下のようなことを書いちゃったりします。
(Bクラスを書き換え例にします)
package jp.co.hoge.callback;
import javax.inject.Inject;
import jp.co.hoge.business.SomethingEjb;
public class B implements MyInterface{
@Inject
SomethingEjb ejb;
@Override
public void doit() {
System.out.println("クラスBの実装");
ejb.callEjb();
}
}
「Injectすればいいんじゃないの、動くんじゃね」と悪魔がささやいたり…。
でも、ふと我に返って「それってCDI管理対象Beanの話でしょ!」と天使君がささやきます。
実際に上記を実行すると、落ちたりはしませんが、EJBとして機能しないためか
情報: クラスBの実装
としか出ませんでした。(Java EE6 + GlassFish 3.1.2.2)
CDI管理対象BeanからEJBを呼ぶ
というわけで次のように書きます。
(Aクラスを書き換え例にします)
package jp.co.hoge.callback;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import jp.co.hoge.business.SomethingEjb;
@Named
@SessionScoped
public class A implements MyInterface, Serializable{
@Inject
SomethingEjb ejb;
@Override
public void doit() {
System.out.println("クラスAの実装");
System.out.println(ejb.callEjb());
}
}
実行すると
情報: クラスAの実装
情報: EJBの実装だよ
おー出た出た。大丈夫だ。
正しい道に進んでいるのかな…
なんか変に悩んでしまうのは、
Java SEの例だったPOJOをCDI管理対象Beanとかにしていいの?
とか変に悩んだりします。
なんかこういうことやってると実は後々メモリの問題とかやばいよ、みたいなことだったりするのか
そういう辺りが全然わからなくて…(^^;
普通はこういう風に書くんだぜ、という例もあまり見なくて…うーんって悩んだり。
同じような悩みをされる人はいるのでしょうか。。。