EJB中的三種bean
1.會話bean(session bean)
負責與客戶端交互,是編寫業務邏輯的地方,在會話bean中可以通過jdbc 直接操作數據庫,
但大多數情況下都是通過實體bean來完成對數據庫得操作。
會話bean 又可以分爲2種
.無狀態會話bean
平常,我們使用最多的是無狀態bean,因爲它的bean 實例可供多個用戶使用,所以它的性能比
有狀態bean高,正因爲一個bean實例被多個用戶使用,那麼,前一個用戶設置的值有可能被後
一個用戶所修改,所以它無法 正確保存某個用戶設置的值,因此是無狀態的
.有狀態會話bean
有狀態bean平常使用的並不多,因爲它的一個bean實例只供一個用戶使用,所以性能開銷比較
大,正因爲它得實例只能被一個用戶使用,那麼,用戶設置的值是不會被其他用戶所修改,所以
可以正確保存用戶設置的值,因此是有狀態的。
2.實體bean(entity bean)
它實際上屬於java 持久化規範(簡稱jpa)裏的技術,jpa的出現主要是爲了簡化現有得持久化開發
工作和整合ORM技術, 結束現在hibernate TOPlink等ORM框架各自爲盈的局面。
3.消息驅動bean(message-driven bean)
它是專門用於異步處理java消息的組件,具有處理大量併發消息的能力。
開發EJB依賴的jar文件
可以在jboss安裝路徑的client目錄下找到,通常會把client目錄下的所有jar文件添加到項目的路徑下
接口可以是本地接口,也可以是遠程接口 EJB屬於業務層
EJB3.0 開發第一個無狀態會話bean
接口
package com.launch.out;
public interface HelloWord {
public String say(String name);
}
實現
package com.launch.impl;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import com.launch.out.HelloWord;
@Stateless
@Remote(HelloWord.class)
public class HelloWordBean implements HelloWord {
public String say(String name) {
return name+"how are you .";
}
}
完成後打成jar包
開發EJB的客戶端
客戶端要調用EJB,它是需要通過jndi去尋找EJB的存根代理對象。
如果客戶端運行在服務器內,我們不需要去爲InitialContext設置應用上下文信息,也不建議設置。
因爲應用服務器會把jndi驅動類等上下文信息添加進系統屬性,創建InitialContext對象時如果沒有指定
Properties參數,InitialContext內部會調用System.getProperty()方法從系統屬性裏讀取必要的上下文信息,
對本例子而言,你可以省略傳入Properties 參數,之所以給InitialContext設置參數,目的是引出相關知識
在實際應用中,如果給InitialContext設置了參數,反而會帶來不可移植的問題
注:創建InitialContext對象時如果沒有指定Properties參數,InitialContext還會在CLASSPATH下尋找
jndi.properties文件 ,並從該文件中加載應用服務器的上下文信息。這樣避免了硬編碼爲InitialContext
設置Properties參數。
jndi.perperties 的設置如下
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming.org.jnp.interfaces
客戶端調用
import javax.naming.*;
import java.util.Properties;
public class test {
public static void main(String args[]){
設置的JNDI的上下文信息
Properties props = new Properties();
//JNDI規範所規定 後面的是JBOSS的JNDI連接工廠
//org.jnp.interfaces.NamingContextFactory這個類是在安裝jboss下client目錄下jnp-clent.jar
// jndi通過這個連接工廠就可以和JBOSS通訊了
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
// 用戶設置命名服務器的連接URL
props.setProperty("java.naming.provider.url", "localhost:1099");
try {
InitialContext ctx = new InitialContext(props);
//根據EJB jndi名稱 查詢HelloWordBean/remote存根代理對象
HelloWord helloworld = (HelloWord) ctx.lookup("HelloWordBean/remote");
System.out.println(helloworld.say("佛山人"));
} catch (NamingException e) {
System.out.println (e.getMessage());
}
}
}
這裏編寫的客戶端程序完全可以部署在另外一臺計算機上,只需要修改其中連接的服務器ip
地址和啓動jboss時綁定相應ip地址即可,這正是ejb的遠程調用特性。
返回的helloword實例對象並不是我們在服務器端編寫得HelloworldBean.
而是一個也實現了Helloworld接口的代理對象。這個代理對象最終遠程調用我們自己編寫的HelloworldBean,
可以加如
System.out.println(helloworld.getClass().getName());
jboss 默認生成的jndi名稱
當EJB發佈到jboss時,如果我們沒有爲它指定全局JNDI名稱或修改過其默認EJB名稱,jboss
就會按照默認的命名規則爲EJB生成全局JNDI名稱。默認的規則如下:
如果把EJB作爲模塊打包進後綴爲*.ear的JAVA EE企業應用文件,默認的全局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://local:8080/jmx-console/
找到jboss
點擊 service=JNDIView進去後
List of MBean operations
java.lang.String.list()
點擊 invoke 按鈕 進去
Global JNDI Namespace
如果看到我們發佈的jndi名稱,就說明是發佈成功了。