客户端使用EJB类似.NET中的webservice的调用。
先来大致了解一下EJB:
ejb容器管理的标准基础设施服务表包括:分布式事务、安全、并发、持久性、资源池和缓冲、接口、负载均衡、容错管理。 EJB规范中有四种对象类型:无状态会话、有状态、实体、消息驱动bean。
这里用一个无状态的会话bean做为例子,学习客户端调用服务端EJB的方法。
RMI远程调用的过程机理如下图:
在客户端使用EJB的整个调用过程中,非常有必要学习Home和Remote接口。
home接口:
调用EJB的生命周期、创建、删除查找EJB;部署ejb时,home interface stub绑定在jndi上。
remote接口:
用于调用EJB上的方法。
整个调用过程机理:
通过上面两图得知,home接口和Remote接口使用都是通过rmi远程调用来实现的。
Stub和skeleton是通过rmic由声明远程对象业务方法的接口产生的。
客户端的方法通过stub对象,通过rmi远程调用,服务端的skeleton对象,然后实现了对远程对象的方法的调用。
下面使用具体代码演示整个调用过程:
1、定义远程Remote接口方法:
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface person extends EJBObject{
public String sayHelloworld() throws RemoteException;
}
这里的方法只负责具体的业务。
继承EJBObject接口,把需要调用的public方法写在里面(这些方法将在SessionBean中实现),注意要声明throws Java.rmi.RemoteException。import java.io.Serializable;
import java.rmi.RemoteException;
import javx.ejb.CreateException;
import javax.ejb.EJBHome;
public interface personHome extends EJBHome{
person create() throws RemoteException,CreateException;
}
这里要引入Serializable,要求是要可序列化的,因为是远程调用。在客户端和服务端传输的是被序列化的数据格式,如果在客户端使用的时候,还需要反序列化。
在home接口中,只负责创建实例。至少生成一个create方法, 注意要声明throws java.rmi.RemoteException和javax.ejb.CreateException。
3、真正ejb方法的实现:
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javx.ejb.SessionContext;
public class personEJB implements SessionBean{
public String sayHelloworld(){
return "Hello World";
}
public personEJB(){};
public void ejbCreate(){};
public void ejbRemove(){};
public void ejbActivate(){};
public void ejbPassivate(){};
public setSessionContext(SessionContext sc){};
}
不能用implents person的方式直接实现远程接口,此处不用抛出RemoteException。
4、发布配置文件ejb-jar.XML,用jar工具生成jar文件,发布工具生成发布使用的jar文件,把.jar文件发布到EJB Server这些操作省略。
5、客户端调用程序:
import javx.naming.*;
import javx.rmi.*;
import java.util.*;
public class TestClient{
public static void main(String[] args){
//这里是通过weblogic的调用的实现,还可以有其他的方式:本地、hashtable的实现等
try {
String m_url ="t3://localhost:7001";
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL,m_url);
Context initial = new InitialContext(h);
Object objref =initial.lookup("person");
personHome home = (personHome)ProtableRemoteObject.narrow(objref,personHome.class);
person ms = home.create();
System.out.println(ms.sayHellworld());
}catch(Exceptoin ex){
System.out.println(ex.getMessage());
}
}
}
客户端调用的时候,使用到了jndi查找远程对象,在上一篇博客中已经有过详述,这里就不再赘述,客户端在调用的时候通过就像使用本地对象一样随意调用远程ejb中的方法。
总结:
服务端ejb中定义的各种方法和接口都是为客户端的调用服务,除了无状态的会话bean还有有状态的会话bean、当然还会引入一系列的事务、安全等等机制,这里的水很深,会在以后的学习中不断深入,这里只对整个调用流程做简单探讨。