開發具有本地接口的無狀態session bean
當通過遠程接口調用EJB時:
首先客戶端需要與ejb建立起socket通信,在通信管道上他們之間需要來回發送IIOP協議消息,因為數據要在網絡進行傳輸,存放數據的java對象必須要進行序列化bean" name="image_operate_51381323502849734" alt="開發具有本地接口的無狀態session
在這個過程中,有網絡通信的開銷、協議解析的開銷、對象序列化的開銷。因為ejb是分布式技術,它允許客戶端與ejb應用在不同一機器上面,所以這些性能開銷也是必然的。
但是在實際生產中,不可避免這種情況:客戶端與EJB應用運行在同一臺機器上的同一個jboss中。
那么這個時候客戶端是否還有必要跟ejb之間走上面的網絡通信呢?
這個時候的客戶端與ejb是在同一個jvm內,他們之間完全可以通過內存進行交互,如果如此,完全可以避免上面流程的性能開銷,所以引入了——本地接口
通過本地接口調用ejb,直接在內存交互,這樣可以避免因網絡通信所造成的各種性能開銷,但有一點需要注意:
只有客戶端與EJB應用都在同一個JVM內運行的時候,才能調用本地接口,否則只能調用遠程接口。
什么情況下客戶端與EJB應用是在同一個JVM?
只要客戶端與EJB發布在同一個jboss內,就可以認為他們在同一個JVM
---------------------------------------------------------------
在原有的HelloWorld項目中,修改HelloWorldBean.java
將@Remote(HelloWorld.class)
修改為@Local(HelloWorld.class) 就可完成本地接口
具有本地接口的無狀態bean已經被開發
運行ANT的deploy將EJB部署到jboss中,通過控制臺可以看到ejb已經成功部署
當EJB部署成功,jboss會為這個本地接口,生成出一個JNDI名稱
開發EJB的客戶端 http://blog.sina.com.cn/s/blog_8020e411010123yl.html博文中講述了
jboss生成JNDI默認命名規則,這里不再贅述
這里生成的JNDI名稱為:HelloWorldBean/local
在客戶端,通過該JNDI名稱,使用本地接口,訪問EJB
此時會報錯,原因是客戶端和EJB不在同一個JVM內
新建一個web項目,將其部署在jboss下,使客戶端與EJB在同一個jboss中,方可使用本地接口
新建一個Test.jsp,將原EJBClient客戶端代碼,復制進來
并講類引入進來(<%@ page import="java.naming.*"%>)
此時 HelloWorld helloWorld =
(HelloWorld)cts.lookup("HelloWorldBean/local");的HelloWorld類不存在,由于不是同一個項目,所以需要將剛才的EJBClient的java Project導入進這個Web Project中
選中這個EJBClient的Web項目,右鍵,Properties
選擇剛才的EJB java Project,點OK
在Test.jsp頁面,完整的導入:
<%@ page import="javax.naming.*,com.test.ejb3.HelloWorld"
%>
<body>
InitialContext();
helloWorld =
(HelloWorld)cts.lookup("HelloWorldBean/local");
//$Proxy3
//hello說:你好,世界!
e){
%>
此時客戶端應用已經開發完成,然后導出war文件
將war文件,拷貝到jboss的發布目錄下進行發布
如果:
InitialContext cts = new InitialContext();
為Application Server指定了JNDI名稱,那此程序只能運行在這個Application Server中
如不寫參數,則其構造函數自動尋找jndi的上下文信息,自動與其綁定
要注意:在EJBClient的Web項目下,引用的HelloWorld接口,并沒有將它的class文件放入該web項目的classpath下
原因是:當加載到HelloWorld類時,沒有找到它時,由于引用了HelloWorld
JavaProject項目,EJB類加載器就會去它的classpath中尋找
所以,當WEB應用和EJB應用部署在同一個JVM內時,并不需要在客戶端應用里面,放入EJB的接口類
如果將EJB接口類放入進客戶端classpath中,有時會導致類型出圖問題
企業中,很有可能客戶端和EJB是部署在同一個JBOSS中,也可能部署在不同機器上
考慮到這兩點,就會選用遠程接口或本地接口
返回到剛才的HelloWorld java Project程序:
新建一個接口:
//繼承HelloWorld的業務方法
public interface HelloWorldLocal extends
HelloWorld{
}
修改實現的bean:
優先調用本地接口
這樣就可以使:當客戶端與EJB在同一個JBOSS中,使用本地接口
客戶端與EJB不在同一個JBOSS中,則使用遠程接口
------------------------------------------------------------------
try{
InitialContext();
(HelloWorld)cts.lookup("HelloWorldBean/remote");//使用遠程接口
//$Proxy3
//明明說:你好,世界!
e){
EJB與客戶端在同一個jboss中,也可用遠程接口訪問
------------------------------------------------------------------
<body>
InitialContext();
(HelloWorldLocal)cts.lookup("HelloWorldBean/local"); //使用本地接口
//$Proxy3
//本地人說:你好,世界!
e){
%>
在Web客戶端與EJB使用同一個jboss,可用本地接口