EJB,一个高层次的框架,总让人觉得神秘莫测.但其实它的实现却出乎意料的简单.表面上看,它只是把Bean从不同的机上分离出去而已.其实我们也不用去理太多它的内部实现,至少在入门阶段是这样的.呵呵.下面开始啦:
参考资料:http://www.soft6.com/know/detail.asp?id=BAIEFJ
<<Mastering Enterprise JavaBeans Third Edition >>By Ed Roman
本例代码是在WebLogic 8.1 的例题改编:
D:\bea\weblogic81\samples\server\examples\src\examples\webservices\basic\statelessSession,由于文档的注释与改编后有出入,这里把全部的注释删除,另在代码外进行说明.
JBoss和JDK的安装这里就不再重复了,不懂的话自己到网上找下.
Hello.java
这是一个远程接口,支持EJB组件暴露的所有业务方法,在客户同EJB对象互交时,需要使用这一接口,窗口厂商会实现这一接口,而相应的实现对象就是EJB对象.EJB对象会将客户请求委派给实际的EJB Bean类.此类必需抛出RemoteException异常.
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface Hello extends EJBObject {
String sayHello(String name) throws RemoteException;
}
HelloLocal.java
Hello EJB组件的本地接口,当酵客户同EJB酵对象互交时,需要使用这一接口.而相应的实现对象就是EJB本地对象.EJB本地对象会将客户请求委派给实际的EJB Bean类.由于是本地接口,所以不需要抛出RemoteException异常.
import javax.ejb.EJBLocalObject;
public interface HelloLocal extends EJBLocalObject
{
public String hello();
}
HelloLocalHome.java
本地Home接口是Home接口的高性能版本.它由EJB服务器提供的工具实现,本地Home接口实现称之为本地Home对象,本地Home对象充当了创建EJB本地对象的工厂.本地Home对象并不是远程对象,因此不必抛出远程异常.
import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;
public interface HelloLocalHome extends EJBLocalHome
{
HelloLocal create() throws CreateException;
}
HelloHome.java
为了创建和销毁EJB对象,开发者需要使用Home接口.Home对象由EJB服务器提供的工具生成.Home对象充当了创建EJB对象的工厂.
create方法还能完成EJB组件的初始化工作,由于EJBHome定义了用于销毁EJB对象的方法,因此HelloHome不用再定义它.
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface HelloHome extends EJBHome {
Hello create()
throws CreateException, RemoteException;
}
HelloBean.java
这是一个无状态的会话Bean.,当初始化和销毁企业Bean实例时,容器将同它互交,但客户并不需要使用这些回调方法.因此在客户代码中绝对看不到它们的调用,因为公公有EJB容器使用它们.HelloBean类存在ejbCreate()方法,同Home对象的create()方法一致.会话Bean不会用到ejbActivate()(激活)和ejbPassivate()(挂起)操作(在有状态Bean中使用!),因此这两个方法为空.
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class HelloBean implements SessionBean {
private static final boolean VERBOSE = true;
private SessionContext ctx;
private void log(String s) {
if (VERBOSE) System.out.println(s);
}
public void ejbActivate() {
log("ejbActivate called");
}
public void ejbRemove() {
log("HelloBean.ejbRemove()");
}
public void ejbPassivate() {
log("HelloBean.ejbPassivate()");
}
public void setSessionContext(SessionContext ctx) {
log("HelloBean.setSessionContext()");
this.ctx = ctx;
}
public void ejbCreate () throws CreateException {
log("HelloBean.ejbCreate()");
}
public String sayHello(String inputStr) {
String retStr = "Run from Jboss:"+ inputStr ;
log(retStr);
return retStr;
}
}
到此全部编码已经完成了,接下来是布署.
首先要写个布署文件,如果用Jbuilder的话可以自动生成.如下:
1.创建一个META-INF文件夹,在此文件夹下面建一个ejb-jar.xml布署文件
2.编写布署文件,内容如下:
<ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<home>com.ycoe.ejb.HelloHome</home>
<remote>com.ycoe.ejb.Hello</remote>
<ejb-class>com.ycoe.ejb.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
这个简单
<ejb-name>:企业Bean的昵称.在部署描述符的其他地方能够引用它,供设置其他参数使用
<home>:Home接口的全限定名(包名也要带上)
<remote>:远程接口的全限定名
<local-home>:本地Home接口的全限定名
<local>:本地接口的全限定名
<ejb-class>:企业Bean类的全限定名
<session-type>:标识企业Bean是有状态的还是无状态的
<transaction-type>:事务
不同的容器可能还要其它的布署文件,具体看容器的说明.
到这里,EJB的所有东西都做好了.剩下打包了.
3.在DOS窗口下进入此文件的目录.以本例为例,进入D:\Eclipse\Hello目录结构如下:
Hello
|_META-INF
| |_ejb-jar.xml
|_com
|_ycoe
|_ejb
|_Hello.java
|_HelloBean.java
|_HelloHome.java
|_HelloLocal.java
|_HelloLocalHome.java
在命令行输入:jar cf Hello.jar com META-INF
各参数作用这里不再说明,上网找吧,到处都是.
这时可以看到在Hello目录下又多了一个Hello.jar文件,这就是我们要的!
4.布署Jar文件.这一步在JBoss下面非常容易.启动JBoss后,把Hello.jar文件复制到%JBOSS_DIST%\server\default\deploy目录下(%JBOSS_DIST%为JBoss安装目录)
可以看到JBoss的输出信息:
SP1/server/default/deploy/Hello.jar
22:16:58,937 INFO [EjbModule] Deploying Hello
22:16:59,546 INFO [ProxyFactory] Bound EJB Home 'Hello' to jndi 'Hello'
22:16:59,546 INFO [EJBDeployer] Deployed: file:/C:/Program Files/jboss-4.0.3SP1/server/default/deploy/Hello.jar
可以看到JAR文件热布署成功!
5.编写测试代码:
Client.java
要调用EJB中的接口,必需先初始化上下文环境.这里由一个专门的方法private static Context getInitialContext() throws NamingException来实现.这是由Jbuilder生成的初始化方法.即使不在本地的EJB服务器,只要更改这里的put(...)里面的路径就可以直接访问到.不同的容器这部分有所区别,具体可以参照容易的API.这里我们使用的是JBoss服务器.这个类中,我们使用了键盘输入与EJB互交的示例,而不是简单的打印而已,可以更好的理解EJB的存在.为了理解EJB的作用,建议再装一个JDK,不同版本的也没关系.在另一个JDK中运行这个程序,或者干脆用另一台电脑,但注意此时要修改下面的初始化上下文环境代码.这里不再多说
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public final class Client {
public Client() {}
public static void main(String[] argv)
throws Exception
{
Properties props = System.getProperties();
Context context = getInitialContext();
Object ref = context.lookup("Hello");
HelloHome helloHome = (HelloHome) PortableRemoteObject.narrow(ref, HelloHome.class);
Hello hello = helloHome.create();
InputStream input = System.in;
byte[] inputBytes = new byte[255];
int count = 0;
String strInput = "";
while (!"exit".equalsIgnoreCase(strInput)) {
try{
count = input.read(inputBytes);
}catch(Exception ex){}
strInput = new String(inputBytes, 0, count);
System.out.println("This is run from client:"+strInput);
hello.sayHello(strInput);
}
hello.remove();
}
private static Context getInitialContext() throws NamingException {
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
environment.put(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
environment.put(Context.PROVIDER_URL, "jnp://localhost:1099");
return new InitialContext(environment);
}
}
测试结果:
编译运行com.ycoe.ejb.Client 从键盘上输入几个字符,回车,可以看到在Client端输出:
hello
This is run from client:hello
sdf
This is run from client:sdf
exit
This is run from client:exit
在JBoss端输出:
23:24:22,593 INFO [STDOUT] HelloBean.setSessionContext()
23:24:22,703 INFO [STDOUT] HelloBean.ejbCreate()
23:24:25,562 INFO [STDOUT] Run from Jboss:hello
23:24:31,046 INFO [STDOUT] Run from Jboss:sdf
23:44:58,250 INFO [STDOUT] Run from Jboss:exit
到这里,全部内容已经完成!祝你好运!
--原创文章,可以任意复制发表,但请注明作者与出处,尊重版权!
BY YCOE