EJB开发第一个无状态会话bean、开发EJB客户端
開發第一個無狀態會話bean
EJB中的三中bean:
會話Bean(Session Bean)
負責與客戶端交互,是編寫業務邏輯的地方,在會話bean中可以通過JDBC直接操作數據庫,但大多數情況下都是通過實體bean來完成對數據庫的操作。
?
實體Bean(Entity Bean)
它實際上屬于java持久化規范(JPA)里的技術,JPA的出現主要是為了簡化現有的持久化開發工作和整合ORM技術,結束現在Hibernate、TopLink等ORM框架各自為營的局面。
?
消息驅動Bean(MessageDriven Bean)
???????? 它是專門用于異步處理Java消息的組件。具有處理大量并發消息的能力。
?
會話bean:
???????? 無狀態會話bean
平常我們使用最多的是無狀態bean,因為它的bean實例可供多個用戶使用,所以它的性能比有狀態bean高。正因為一個bean實例被多個用戶使用,那么前一個用戶設置的值可能被后一個用戶所修改,所以它無法正確保存某個用戶設置的值,因此是無狀態的。
?
???????? 有狀態會話bean
有狀態會話bean平常使用的并不多,因為它的一個bean實例只供一個用戶使用,所以性能開銷比較大,正因為它的實例只被一個用戶使用,那么用戶設置的值是不會被其他用戶所修改的,所以可以正確保存用戶設置的值,因此是有狀態的。
?
開發一個無狀態會話bean
???????? 開發工具:MyEclipse。
???????? 開發EJB依賴的jar文件:Jboss安裝路徑下的client下,通常把所以的jar添加到項目。
結構:
???????? 接口(可以是遠程接口或本地接口)
???????? 實現類
?
步驟:
1.新建一個JavaProject:HelloWorld
2.導入所有的client的jar包
?
?
3.新建一個接口HelloWorld 在cn.hqu.ejb3下
添加方法 String sayHello(String name);
?
4.創建實現類:
新建一個類HelloWorldBean,實現HelloWorld接口,在包 cn.hqu.ejb3.impl;
實現方法里面:
return name+"說:你好!";
5.把這兩個類變成ejb3
在HelloWorldBean加入注解 @Stateless
指定這個ejb是一個無狀態會話bean;
?
指定這個接口是一個遠程接口:(默認是本地接口)
在HelloWorldBean加入注解@Remote(HelloWorld.class) 。
Ejb開發完成
@Stateless
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld {
??? @Override
??? public String sayHello(String name) {
??????? // TODO Auto-generated method stub
??????? return name+"說:你好!";
??? }
}
?
6.進行發布:
打成jar包,可以通過eclipse打包或者通過ant打包。
這里使用MyEclipse,右擊項目選擇Export→jar file 。
?
發布:先啟動JBoss,復制打包好的jar拷貝到JBoss的server/default/deploy下,這樣就完成ejb的部署;這樣就發布成功了;會話bean開發完了。
?
開發EJB的客戶端
Ejb在軟件分層結構上,屬于業務層,通常要被客戶端調用,這里用Java類做ejb客戶端。
新建類EJBClient 在包cn.hqu.test,在main里面編寫EJB的調用代碼:
?
package cn.hqu.test;import java.util.Properties;import javax.naming.InitialContext; import javax.naming.NamingException;import cn.hqu.ejb3.HelloWorld;public class EJBClient {/*** @param args*/public static void main(String[] args) {Properties pros = new Properties();pros.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");pros.setProperty("java.naming.provider.url", "localhost:1099");try {InitialContext ctx = new InitialContext(pros);HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");System.out.println(helloworld.sayHello("蘇志達"));} catch (NamingException e) {e.printStackTrace();}}}執行客戶端(main方法);調用成功;
?
代碼含義:客戶端要調用ejb,要通過JNDI去尋找EJB的xx代理對象,JNDI是一套用來訪問命名服務器的API,也是JavaEE里面的規范。
?
設置JNDI訪問環境信息
如同數據庫一樣,根據訪問命名服務器不同,為上下文設置的驅動類和URL也是不同的,如下面是訪問Sun應用服務器的上下文信息:
如果客戶端運行在應用服務器內,我們不需要為InitlalContext設置應用服務器的上下文信息,也不建議設置。因為應用服務器啟動時會把JNDI驅動類等上下文信息添加進系統屬性,創建InitialContext對象時如果沒有指定Properties參數,InitialContext內部會調用System.getProperty()方法從系統屬性里獲得必要的上下文信息。對本例子而言,可以省略傳入的props參數,在實際應用中如果給InitialContext設置了參數,反而會帶來不可移植的問題。
???????? 注:創建InitialContext對象時如果沒有指定Properties參數,InitialContext還會在classpath下尋找jndi.properties文件,并從該文件中加載應用服務器的上下文信息,這樣避免了硬編碼為InitialContext設置Properties參數。
InitialContext ctx = newInitialContext();
jndi.properties的配置如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost\:1099
?
提示:這里編寫的客戶端程序完全可以部署在另外一臺計算機上,只需要修改其中的連接服務器IP地址和啟動Jboss時綁定相應IP地址即可。這正是EJB的遠程調用特性。在第19行返回的helloworld實例對象并不是我們在服務器編寫的HelloWorldBean,而是一個也實現了HelloWorld接口的代理對象,這個代理對象最終遠程調用我們自己編寫的HelloWorldBean,在19后加入如下代碼,即可看到這個代理對象的類名:
System.out.println(helloworld.getClass().getName())
?
?????? Jboss默認生成的JNDI名稱
???????? 當EJB發布到Jboss時,如果我們沒有為它指定全局JNDI名稱或者修改過其默認EJB名稱,Jboss就會按照默認的命名規則為EJB生成全局JNDI名稱,默認是命名規則如下:
???????? 本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
???????? 遠程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
????????
???????? EAR-FILE-BASE-NAME為ear文件的名稱,EJB-CLASS-NAME為EJB的非限定類名。
例:把HelloWorld應用作為EJB模塊打包進名為HelloWorld.ear的企業應用文件,它的遠程接口的JNDI名稱是:HelloWorld/HelloWorldBean/remote
?
???????? 如果把EJB應用打包成后綴為*.jar的模塊文件,默認全局JNDI名稱是
???????? 本地接口:EJB-CLASS-NAME/local
???????? 遠程接口:EJB-CLASS-NAME/remote
例:把HelloWorld應用打包成HelloWorld.jar文件,它的遠程接口的JNDI名稱是:
HelloWorldBean/remote
代碼:http://pan.baidu.com/s/1dDckCXN
總結
以上是生活随笔為你收集整理的EJB开发第一个无状态会话bean、开发EJB客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java ssm旅游网站系统源码jsp
- 下一篇: vue商城秒杀倒计时功能