三个基本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提供的功能.