简单的EJB 及其部署文件

板桥里人 https://www.jdon.com 2002/06/29/

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

 

Java实用系统开发指南