三個基本class
EJB最少也需要三個class, remote interface, home interface, and bean implementation(bean行為).
1. remote interface 用來揭示EJB對外的一些方法.在這個例子中,the remote interface 就是org.jboss.docs.interest.Interest.
ackage org.jboss.docs.interest;
import javax.ejb.EJBObject; import java.rmi.RemoteException; /** This interface defines the `Remote' interface for the `Interest' EJB. Its single method is the only method exposed to the outside world. The class InterestBean implements the method. */ public interface Interest extends EJBObject { public double calculateCompoundInterest(double principle, double rate, double periods) throws RemoteException; }
|
?
2.home interface 是用來規定怎樣創建一個實現remote interface的bean. 在本例中home interface 是 org.jboss.docs.InterestHome.
package org.jboss.docs.interest;
import java.io.Serializable; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; /** This interface defines the `home' interface for the `Interest' EJB. */ public interface InterestHome extends EJBHome { /** Creates an instance of the `InterestBean' class on the server, and returns a remote reference to an Interest interface on the client. */ Interest create() throws RemoteException, CreateException; }
|
3.bean implementation 是提供方法的實現,這些方法在上述兩種interface中都有規定了,在本例中是兩個方法: calculateCompoundInterest和create().
這個bean implementation 是 org.jboss.docs.interest.InterestBean.
package org.jboss.docs.interest;
import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; /** This class contains the implementation for the `calculateCompoundInterest' method exposed by this Bean. It includes empty method bodies for the methods prescribe by the SessionBean interface; these don't need to do anything in this simple example. */ public class InterestBean implements SessionBean { public double calculateCompoundInterest(double principle, double rate, double periods) { System.out.println("Someone called `calculateCompoundInterest!'"); return principle * Math.pow(1+rate, periods) - principle; } /** Empty method body */ public void ejbCreate() {}
/** Every ejbCreate() method ALWAYS needs a corresponding ejbPostCreate() method with exactly the same parameter types. */ public void ejbPostCreate() {}
/** Empty method body */ public void ejbRemove() {} /** Empty method body */ public void ejbActivate() {}
/** Empty method body */ public void ejbPassivate() {} /** Empty method body */ public void setSessionContext(SessionContext sc) {} }
|
?
這些classes必須打包進一個JAR文件中,JAR文件中包含了目錄結構和包的層次.在本例中,這些classes是在包org.jboss.docs.interest, 這樣他們需要在目錄org/jboss/docs/interest/ 下.
部署發布描述器ejb-jar.xml和jboss.xml
在JAR文檔創建之前,還需要一個叫META-INF的目錄,這是存放部署發布描述器的(一般叫ejb-jar.xml).大部分商用EJB Server提供圖形化工具來編輯這個 描述器.在JBoss中需要手工:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar> <description>JBoss Interest Sample Application</description> <display-name>Interest EJB</display-name> <enterprise-beans> <session> <ejb-name>Interest</ejb-name> <!-- home interface --> <home>org.jboss.docs.interest.InterestHome</home> <!-- remote interface --> <remote>org.jboss.docs.interest.Interest</remote> <!-- bean implementation --> <ejb-class>org.jboss.docs.interest.InterestBean</ejb-class> <!--bean 的類型 這里是Stateless --> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> </session> </enterprise-beans> </ejb-jar> |
在本例中,一個包中只有一個EJB 這樣就不用描述多個EJB之間是怎樣交互的.
盡管對于所有的EJB服務器,ejb-jar.xml部署描述器的格式是一樣的(更多精確的定義可以從sun得到DTD).它并沒有規定所有的必須的信息,比如如何將EJB-NAME和JNDI naming service聯系起來.
缺省情況下,JNDI name將使用在ejb-jar.xml中<ejb-name>XXX</ejb-name>中的XXX來使用EJB的home interface.
但是如果有多個EJB,在ejb-jar.xml中,在<ejb-name>XXX</ejb-name>中XXX就不能用同一個名字了,一般格式是"[application name]/[bean name]".
那么如果再按照缺省情況,JNDI name就可能找不到你的應用程序的入口了,因此我們要特別規定一下.這就需要在jboss.xml中規定:
<?xml version="1.0" encoding="UTF-8"?> <jboss> <enterprise-beans> <session> <ejb-name>Interest</ejb-name> <jndi-name>interest/Interest</jndi-name> </session> </enterprise-beans> </jboss> |
這樣,你所有叫Interest文件都被梆定到JNDI name:interest/Interest下面
jndi.properties
雖然有了上面你的應用程序和JNDI name的梆定,但是一旦部署發布到JBoss服務器上,你還需要一個jndi.properties文件,以告訴調用你程序的客戶端請求到哪里去初始化JNDI naming service.
?
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
?
|
在本例中,客戶端請求將尋找Interest 這個bean, 然后得到這個bean的home interface. home interface是用來得到這個bean的remote interface.最后,客戶端請求將通過remote interface來使用由EJB提供的功能.