2011年5月30日 星期一

SCEA - Adding Functionality to your beans

Calling Beans from other Beans

作法:lookup other bean's interface via JNDI , then call the business method on the ejb oject via the interface


這裡有一個很特別的地方,就是在透過JNDI取other bean時,實際上是不需要再次透過Remote (RMI-IIOP)方式來取回ejb,只需要透過以下的範例直接做,就可以達成在bean當中呼叫其他的bean:




Context ctx = new InitialContext();


Object result = ctx.lookup(TaxRate.class.getName());


TaxTate tr = (TaxRate) resut;



上面的做法是EJB2.x系列以前使用的,到了EJB 3.0,可以直接透過annotation來處理,像是以下這樣




@EJB TaxRate tr;



Annotations

  • Common Annotations


常用的annotation,支援SB,EB,MDB如下:


@name // unqualified name of the class




@Stateless(name="TR")


public class TaxRateBean implements TaxRate{


}



@mappedName //這通常是給container使用得,若有設置這樣的資訊會比較難以移植到不同的平台上




@Stateful(mappedNmae="java:comp/env/ejb/CartBean")


public class CartBean implements Cart{


}



@description //通常做為描述標示使用




@MessageDriven(description="Listens for purchase messages")


public class PurchaseMDB implements MessageListener{


}




  • Business interface Annotations


Business interface在 EJB 3.0以後再也不用自己痛苦宣告實作了,通通靠POJOs + annotation來達成




[caption id="attachment_379" align="alignnone" width="700" caption="business interface"]business interface[/caption]

  • Other Stateful Annotations


@remove(retainIfException=false)


 If true, the stateful session bean will not be removed if an exception is thrown from the designated method.




[caption id="attachment_380" align="alignnone" width="444" caption="retainIfException"]retainIfException[/caption]

Dependency Injection

存取物件時可使用的annotation為@Resource與@EJB,@PersistenceContext




  • Resource References


用來設置一個在Bean的實體環境中,賦予他一個參數(物件成員),例如:




@Resource SessionContext context;


TaxRate tr = (TaxRate)context.lookup(TaxRate.class.getName());


//不過老實說sessioncontext好像透過ide都會自動幫忙給就是



上面的例子其實也等同於以下的做法,只是若使用annotation會是比較簡單輕量的作法




InitialContext context = new InitialContext();


TaxRate tr = (TaxRate)context.lookup(TaxRate.class.getName());



在J2EE 環境中,若要取得reference就請使用@Resource,而這個annotation可支援的有java.sql.DataSource , javax.transaction.UserTransaction , javax.jms.Queue , javax.ejb.SessionContext , org.omg.CORBA.ORB




@Resource(name="jdbc/xxx",type=Datasource.class)


DataSource dataSource;



除了在一般的成員設定中可以使用@Resource,也可以用來設置在method身上,通常都是用在 setter部分( setter-injection)




@Resource


private void setMyDataSource(DataSource ds){


myDataSource = ds;


}


private myDataSource;




  • @EJB


@EJB的注入也可分成兩種方式,一個是class level,另外一個是member level




@EJB(


name="ejb/pricer";


beanInterface=Pricer.class;


beanName="pricer",


description="this bean is used to calculate prices."


)


private Pricer pricer;


在上面的案例就是member level,底下來看看Class Level長得如何,下面這例子是在ejb中注入ejb

@EJB(name="ejb/TaxRate", beanInterface="TaxRate.class")

@Stateless

public class PricerBean implements Pricer{

public void doxxx(){


InitialContext context = new InitialContext();


TaxRate tr = (TaxRate)context.lookup("java:comp/env/ejb/TaxRate");


}


}

Interceptors

跟AOP有關的議題來了,interceptors攔截器是一種自動化被呼叫的method,這類型的工作通常都比較像是在主要的business method中,為了附加一些特殊性的輔助功能(像是log紀錄、metadata 保存、auditing、security checking等等),在EJB3.0當中,interceptor 可以用在Session beans 以及Message Driven beans,而interceptor method 可以被宣告在bean class中使用或甚至是一個外部的class。


設計一個 interceptor class方法如下




[caption id="attachment_382" align="alignnone" width="649" caption="LoggerInterceptor"]LoggerInterceptor[/caption]

 若要在EJB當中注入Interceptor 則直接以annotaion注入即可,當然若要在bean class中自己設計interceptor method則是自行注入一個@AroundInvoke的method,相關用法如下




[caption id="attachment_383" align="alignnone" width="654" caption="@Interceptors"]@Interceptors[/caption]

 

[caption id="attachment_384" align="alignnone" width="655" caption="internal interceptor"]internal interceptor[/caption]

 

沒有留言: