読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

Java EE6の開発でよく悩むこと ~ コールバックを例に ~

Java EE 6 Inject CDI EJB

Java EE6の開発をしていて、「自分がやっていることは正しいのか…」と悩み、迷うことがあります。
わかりやすく自分が実際に迷った道を書いてみます。

例題がJava SEで書かれている時

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関数の代わりに、ボタンが押されたらコールバック処理を各々呼ぶ、みたいな記述にしてます。

Java EEだと…

上記の単純な例は普通に書けるのがわかりました。

でも実際には、クラス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とかにしていいの?

とか変に悩んだりします。

なんかこういうことやってると実は後々メモリの問題とかやばいよ、みたいなことだったりするのか
そういう辺りが全然わからなくて…(^^;
普通はこういう風に書くんだぜ、という例もあまり見なくて…うーんって悩んだり。

同じような悩みをされる人はいるのでしょうか。。。

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村