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{@Overridepublic void setSessionContext(SessionContext sessionContext) throws EJBException, RemoteException {System.out.println("setSessionContext");}@Overridepublic void ejbRemove() throws EJBException, RemoteException {System.out.println("ejbRemove");}@Overridepublic void ejbActivate() throws EJBException, RemoteException {System.out.println("ejbActivate");}@Overridepublic 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/javaeehttp://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");//服务器ipprops.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菜单下查看