首页 > 代码库 > 如何开发EJB?

如何开发EJB?

EJB开发分为两部分:开发EJB和使用EJB

本文示例将使用EJB2.0 :1.工作需要;2.EJB3.0相对于2.0变动不大(添加注解,JPA替换实体Bean实现)

开发EJB的流程

以开发stateless SessionBean为栗.

1.编写SessionBean。需要实现SessionBean接口,并额外添加ejbCreate()方法

2.编写Home接口和Remote组件接口。

Remote接口扩展EJBObject接口,添加SessionBean中方法,并抛出异常RemoteException。

Home接口扩展EJBHome接口,添加create()方法,返回Remote组件,抛出异常CreateException、RemoteException。

3.编写ejb-jar.xml

4.打包

5.部署到J2EE服务器

举个栗子

首先你需要个javax.ejb-api.jar

软件环境

开发环境:intellij idea 13

服务器:glassfish 4

目录结构


package com.ejb.bean.sessionbean;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import java.rmi.RemoteException;

/**
 * Created by Tony.Sun on 7/17/2014.
 */
public class GreetingBean implements SessionBean{
    @Override
    public void setSessionContext(SessionContext sessionContext) throws EJBException, RemoteException {
        System.out.println("setSessionContext");
    }

    @Override
    public void ejbRemove() throws EJBException, RemoteException {
        System.out.println("ejbRemove");
    }

    @Override
    public void ejbActivate() throws EJBException, RemoteException {
        System.out.println("ejbActivate");
    }

    @Override
    public void ejbPassivate() throws EJBException, RemoteException {
        System.out.println("ejbPassivate");
    }

    /**
     * 额外添加的ejbCreate方法
     */
    public void ejbCreate()
    {
        System.out.println("ejbCreate");
    }

    /**
     * 问候,没人规定每次都要say hello啊
     * @return
     */
    public String greet()
    {
        return "f u c k y o u,EJB world!";

    }
}

package com.ejb.bean.sessionbean;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

/**
 * Created by Tony.Sun on 7/17/2014.
 */
public interface GreetingRemote extends EJBObject {
    String greet() throws RemoteException;
}

package com.ejb.bean.sessionbean;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import java.rmi.RemoteException;

/**
 * Created by Tony.Sun on 7/17/2014.
 */
public interface GreetingHome extends EJBHome {
    GreetingRemote create() throws CreateException,RemoteException;
}

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
         version="3.1">
    <enterprise-beans>
        <session>
            <ejb-name>greetingbean</ejb-name>
            <home>com.ejb.bean.sessionbean.GreetingHome</home>
            <remote>com.ejb.bean.sessionbean.GreetingRemote</remote>
            <ejb-class>com.ejb.bean.sessionbean.GreetingBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Bean</transaction-type>
        </session>
    </enterprise-beans>
</ejb-jar>

打包什么的太费事直接用IDE部署了,(我们只是代码的搬运工 ^ _ ^)


使用EJB

Bean已经部署在服务器上了,现在要调用Bean,具体步骤如下

1.引用glassfish/lib下gf-client.jar

2.获取JNDI上下文服务 new InitContext()。在服务器上使用时InitContext不需要参数也可以成功运行,独立程序使用时需要传递参数(详见栗子)。

3.通过上下文服务查找Bean服务

4.使用PortableRemoteObject进行窄化,并转换成Home对象

5.使用Home接口对象create() Remote服务接口

6.通过服务接口调用相关方法

来个栗子

package com.ejb.bean.sessionbean;

import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;
import java.util.Properties;

/**
 * Created by Tony.Sun on 7/17/2014.
 */
public class GreetingTest {

    public static void main(String[] args) throws NamingException, RemoteException, CreateException {
        Properties props = new Properties();
        //这些参数根据不同服务器设置不同,具体视服务器而定
        props.put("java.naming.factory.initial", "com.sun.enterprise.naming.impl.SerialInitContextFactory");
        props.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
        props.put("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
        //服务器ip
        props.put("org.omg.CORBA.ORBInitialHost", "localhost");
        //EJB服务端口
        props.put("org.omg.CORBA.ORBInitialPort", "3700");
        //获取JNDI上下文服务 new InitContext()。
        //在服务器上使用时InitContext不需要参数也可以成功运行,独立程序使用时需要传递参数(详见栗子)。
        Context ctx = new InitialContext(props);
        //通过上下文服务查找Bean服务
        Object obj = ctx.lookup("java:global/demo_ejb_exploded/greetingbean");
        //使用PortableRemoteObject进行窄化,并转换成Home对象
        GreetingHome home = (GreetingHome) PortableRemoteObject.narrow(obj,GreetingHome.class);
        //使用Home接口对象create() Remote服务接口
        GreetingRemote remote = home.create();
        //通过服务接口调用相关方法
        String greet = remote.greet();

        System.out.print(greet);
    }
}


运行结果

f u c k y o u,EJB world!
Process finished with exit code 0


补充:

关于JNDI命名服务语法,这一点比较坑,不同服务器厂商提供的都不一样,以glassfish为栗,JNDI语法为

java:global/[应用名称]/模块名称/Bean名称

关于应用名称什么时候使用:当你的Bean.jar被打包在其他war包中的时候使用

关于如何确定模块名称:localhost:4848下Applications菜单下查看