作法: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"]
- 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"]
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"]
若要在EJB當中注入Interceptor 則直接以annotaion注入即可,當然若要在bean class中自己設計interceptor method則是自行注入一個@AroundInvoke的method,相關用法如下
[caption id="attachment_383" align="alignnone" width="654" caption="@Interceptors"]
[caption id="attachment_384" align="alignnone" width="655" caption="internal interceptor"]
沒有留言:
張貼留言