EJB 3.0(Public Draft)入門記 Simplified API Chapter3 その2
前回うまくいかなかったローカルインタフェースを使用したEJBへのアクセスですが、根本的に勘違いしてたのでもういちどやり直します。
- 登場人物はClientとShoppingCartBeanとCalculatorBean。
- ShoppingCartBeanはリモートインタフェースを持っているステートフルセッションBean。
- CalculatorBeanはローカルインタフェースを持っているステートレスセッションBean。(CalculatorにもCalculatorBeanにも@Localや@Remoteが指定されていませんが、Beanクラスが単一のインタフェースを実装している場合はそのインタフェースはデフォルトでローカルインタフェースになります。「3.2 Business Interfaces」より。)
- Client → ShoppingCartBean → CalculatorBeanと呼び出します。(前回はClient → CalculatorBeanとしていて、EJBコンテナ外からローカルインタフェースを使用したEJBアクセスを行っていたためうまくいかないのでした。)
ソースコードはこんなカンジ。ほぼJBossのサンプルのパクリだったりします。
public interface Calculator { public int add(int x, int y); public int subtract(int x, int y); }
@Stateless public class CalculatorBean implements Calculator { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } }
public interface ShoppingCart { void buy(String product, int quantity); HashMapgetCartContents(); }
@Stateful @Remote({ShoppingCart.class}) public class ShoppingCartBean implements ShoppingCart { private HashMapcart = new HashMap (); public void buy(String product, int quantity) { if (cart.containsKey(product)) { int currq = cart.get(product); cart.put(product, getCalculator().add(currq, quantity)); } else { cart.put(product, quantity); } } public HashMap getCartContents() { return cart; } private Calculator getCalculator() { try { InitialContext ctx = new InitialContext(); return (Calculator) ctx.lookup(Calculator.class.getName()); } catch (NamingException e) { throw new RuntimeException(e); } } }
public class Client { public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); ShoppingCart cart = (ShoppingCart) ctx.lookup(ShoppingCart.class.getName()); cart.buy("おにぎり", 3); cart.buy("お茶", 2); cart.buy("おにぎり", 1); System.out.println(cart.getCartContents()); } }
ちなみに、ShoppingCartBeanがCalculatorを知るには@EJBアノテーションが使えるはずなのですが、とりあえず自分でlookupしてみました。
前回のbuild.xmlでデプロイしてClientを実行すると結果はこうなります。
{おにぎり=4, お茶=2}
成功です! あと、サーブレットからもCalculatorBeanが呼び出せました。
追記
コードが間違っていたので直しました。実はShoppingCartBeanがShoppingCartをimplementsしていなかったのです。でもこれはこれで動いていました。どうやら必ずしもインタフェースを実装していなくても@Remote({ShoppingCart.class})というアノテーションでビジネスインタフェースが示せれば動くようです、少なくともJBossでは。既存のEJBっぽいといえるのかな?