EJB代表企業(yè)Java Beans。 EJB是J2EE平臺的一個重要組成部分。 J2EE平臺擁有基于組件的架構(gòu),可提供多層次,分布式和高事務(wù)功能的企業(yè)級應(yīng)用。
EJB提供了一個架構(gòu)來開發(fā)和部署考慮穩(wěn)健性,高可擴展性和高性能的基于組件的企業(yè)應(yīng)用程序。 EJB應(yīng)用程序可以部署在任何符合J2EE 1.3標(biāo)準(zhǔn)規(guī)范的應(yīng)用服務(wù)器上。我們將在本教程中討論EJB 3.0。
簡化大型企業(yè)級應(yīng)用程序的開發(fā)。
應(yīng)用服務(wù)器/ EJB容器提供了最像事務(wù)處理,日志記錄,負(fù)載均衡,持久性機制,異常處理等系統(tǒng)級的服務(wù)。開發(fā)者只需注重于應(yīng)用程序的業(yè)務(wù)邏輯。
EJB容器管理EJB事例的生命周期,因此開發(fā)人員不需要擔(dān)心何時創(chuàng)建/刪除EJB對象
EJB主要的三種類型將在下面進行簡要描述:
類型 | 描述 |
---|---|
會話Bean Session Bean | 會話bean在單個會話特定用戶的存儲數(shù)據(jù)。它可以是有狀態(tài)或無狀態(tài)的。相比于實體bean是資源較少。會話bean得到盡快的用戶會話終止銷毀。 |
實體Bean Entity Bean | 實體Bean表示持久性數(shù)據(jù)存儲。用戶數(shù)據(jù)可以通過實體bean可以保存到數(shù)據(jù)庫,以后可以從實體bean的數(shù)據(jù)庫中檢索。 |
消息驅(qū)動bean Message Driven Bean | 消息驅(qū)動Bean在JMS(Java消息服務(wù))的環(huán)境中使用。消息驅(qū)動Bean可以從外部實體消耗JMS消息,并采取相應(yīng)的行動。 |
EJB是Java的框架,因此第一個要求是JDK已經(jīng)安裝在你的機器上。
JDK | 1.5或以上。 |
---|---|
Memory 內(nèi)存 | 沒有最低要求。 |
Disk Space 磁盤空間 | 沒有最低要求。 |
Operating System 操作系統(tǒng) | 沒有最低要求。 |
現(xiàn)在打開控制臺并執(zhí)行以下java命令。
OS | 任務(wù) | 命令 |
---|---|---|
Windows | 打開命令控制臺 | C:> Java的版本 |
Linux | 打開命令終端 | $ Java的版本 |
Mac | 打開終端 | 機:?$約瑟夫Java的版本 |
讓我們來驗證所有操作系統(tǒng)的輸出︰
OS | 產(chǎn)量 |
---|---|
Windows | Java“1.6.0_21”版本 Java(TM)SE運行時環(huán)境(build 1.6.0_21-b11) Java熱點(TM)64位服務(wù)器VM(build 23.21-b01, mixed mode) |
Linux | Java“1.6.0_21”版本 Java(TM)SE運行時環(huán)境(build 1.6.0_21-b11) Java的熱點(TM)64位服務(wù)器VM(build 23.21-b01, mixed mode) |
Mac | Java“1.6.0_21”版本 的Java(TM)SE運行時環(huán)境(build 1.6.0_21-b11) Java的熱點(TM)64位服務(wù)器VM(build 23.21-b01, mixed mode) |
如果您沒有安裝Java,請安裝Java軟件開發(fā)工具包(SDK) http://www.oracle.com/technetwork/java/javase/downloads/index.html 。本教程使用Java 1.6.0_21作為安裝版本。
設(shè)置JAVA_HOME環(huán)境變量,使之指向安裝在您機器上Java的基本目錄位置。例如
OS | 產(chǎn)量 |
---|---|
Windows | 環(huán)境變量JAVA_HOME設(shè)置為C:\Program Files\Java\jdk1.6.0_21 |
Linux | export JAVA_HOME=/usr/local/java-current |
Mac | export JAVA_HOME=/Library/Java/Home |
將 Java 編譯器位置追加到系統(tǒng)路徑
OS | 產(chǎn)量 |
---|---|
Windows | 追加的字符串;C:\Program Files\Java\jdk1.6.0_21in 到系統(tǒng)變量,路徑的末尾 |
Linux | export PATH=$PATH:$JAVA_HOME/bin/ |
Mac | 不需要 |
使用Java - version命令驗證如上所述安裝的Java。
下載最新版本的NetBeans IDEhttps://netbeans.org/downloads/index.html 。在寫這篇教程的時候,我下載的Netbeans 7.3里面自帶JDK 1.7捆綁在一起。使用以下鏈接http://www.oracle.com/technetwork/java/javase/downloads/index.html
OS | 安裝程序名稱 |
---|---|
Windows | Netbeans 7.3 |
Linux | Netbeans 7.3 |
Mac | Netbeans 7.3 |
您可以下載最新版本的JBoss服務(wù)器http://www.jboss.org/jbossas/downloads/ 。根據(jù)下OS下載對應(yīng)的檔案。提取Jboss到你機器上的任意位置。
OS | 文件名 |
---|---|
Windows | jboss-5.1.0.GA-jdk6.zip |
Linux | 的jboss-5.1.0.GA-src.tar.gz |
Mac | 的jboss-5.1.0.GA-src.tar.gz |
打開插件窗口使用工具 > 插件。打開"可用插件"標(biāo)簽和"JavaWeb 和 EE"類別下選擇"EJB 和耳"和"Java EE 基地"。單擊安裝按鈕。Netbeans 會下載并安裝相應(yīng)的插件。驗證插件安裝使用"安裝"選項卡。
Open Plugin window using Tools > Plugins. Open "Available Plugin" tab and select "Java EE Base" and "EJB and EAR" under "Java Web and EE" category. Click install button. Netbeans will download and install the respective plugins. Verify plugins installation using "Installed" tab.
轉(zhuǎn)到服務(wù)選項卡,并用鼠標(biāo)右鍵單擊服務(wù)器來添加新的服務(wù)器。
Go to Services tab and right click on servers to add a new server.
添加服務(wù)器事例向?qū)⒋蜷_。選擇JBoss和在下一步輸入相關(guān)細(xì)節(jié),在NetBeans中配置服務(wù)器。
Add Server Instance wizard will open. Select JBoss and in next step enter the relevant details to configure server in netbeans.
一旦一切都cofigured,你會看到以下畫面。
下載最新版本的PostgreSQL數(shù)據(jù)庫服務(wù)器http://www.postgresql.org/download/ 。本教程下載的是PostgreSQL 9.2
OS | 安裝程序名稱 |
---|---|
Windows | PostgreSQL 9.2 |
Linux | PostgreSQL 9.2 |
Mac | PostgreSQL 9.2 |
若要創(chuàng)建一個簡單的 EJB 模塊,我們將使用 NetBeans"新建項目"向?qū)?/span>。在以下示例中,我們將創(chuàng)建一個名為Component的 ejb 模塊項目。
在NetBeans IDE中,選擇File > New Project > 文件>新建項目>。你會看到以下畫面。
選擇項目類型下,Java EE 項目類別作為 Ejb 模塊。單擊下一步 > 按鈕。您將看到下圖所示的畫面。
輸入項目名稱和位置。單擊下一步>Next > 按鈕。你會看到以下畫面。
選擇服務(wù)器作為JBoss應(yīng)用服務(wù)器 。單擊Finish按鈕。你會看到NetBeans中創(chuàng)建以下項目。
輸入會話bean名稱和包名稱。單擊Finish按鈕。你會看到NetBeans中創(chuàng)建以下EJB類。
LibrarySessionBean -無狀態(tài)會話bean
LibrarySessionBeanLocal -本地接口的會話bean
因為我們要更改到本地接口到遠(yuǎn)程接口去訪問基于控制臺應(yīng)用程序中的 ejb,遠(yuǎn)程/本地接口用于公開 ejb 已實施的業(yè)務(wù)方法。
LibrarySessionBeanLocal被重命名為LibrarySessionBeanRemote和LibrarySessionBean實現(xiàn)LibrarySessionBeanRemote接口。
LibrarySessionBeanRemote
package com.tutorialspoint.stateless; import java.util.List; import javax.ejb.Remote; @Remote public interface LibrarySessionBeanRemote { void addBook(String bookName); List getBooks(); }
LibrarySessionBean
package com.tutorialspoint.stateless; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateless; @Stateless public class LibrarySessionBean implements LibrarySessionBeanRemote { List<String> bookShelf; public LibrarySessionBean(){ bookShelf = new ArrayList<String>(); } public void addBook(String bookName) { bookShelf.add(bookName); } public List<String> getBooks() { return bookShelf; } }
在項目資源管理器窗口中選擇EjbComponent項目 Select EjbComponent project in Project Explorer window
右鍵點擊它,打開上下文菜單。 Right click on it to open context menu.
選擇清理并生成。 Select clean and build.
你會看到在NetBeans控制臺輸出以下內(nèi)容。
ant -f C:EJBEjbComponent clean dist init: undeploy-clean: deps-clean: Deleting directory C:EJBEjbComponentuild Deleting directory C:EJBEjbComponentdist clean: init: deps-jar: Created dir: C:EJBEjbComponentuildclasses Copying 3 files to C:EJBEjbComponentuildclassesMETA-INF Created dir: C:EJBEjbComponentuildempty Created dir: C:EJBEjbComponentuildgenerated-sourcesap-source-output Compiling 2 source files to C:EJBEjbComponentuildclasses warning: [options] bootstrap class path not set in conjunction with -source 1.6 Note: C:EJBEjbComponentsrcjavacom utorialspointstateless LibraryPersistentBean.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 warning compile: library-inclusion-in-archive: Created dir: C:EJBEjbComponentdist Building jar: C:EJBEjbComponentdistEjbComponent.jar dist: BUILD SUCCESSFUL (total time: 3 seconds)
在服務(wù)窗口服務(wù)器下選擇JBoss應(yīng)用服務(wù)器 Select JBoss application server under Servers in Services window
右鍵點擊它,打開上下文菜單。 Right click on it to open context menu.
選擇啟動。 Select start.
你會看到下面的輸出在NetBeans下JBoss應(yīng)用服務(wù)器輸出。
Calling C:jboss-5.1.0.GAin un.conf.bat ========================================================================= JBoss Bootstrap Environment JBOSS_HOME: C:jboss-5.1.0.GA JAVA: C:Program Files (x86)Javajdk1.6.0_21injava JAVA_OPTS: -Dprogram.name=run.bat -Xms128m -Xmx512m -server CLASSPATH: C:jboss-5.1.0.GAin un.jar ========================================================================= 16:25:50,062 INFO [ServerImpl] Starting JBoss (Microcontainer)... 16:25:50,062 INFO [ServerImpl] Release ID: JBoss [The Oracle] 5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634) ... 16:26:40,420 INFO [TomcatDeployment] deploy, ctxPath=/admin-console 16:26:40,485 INFO [config] Initializing Mojarra (1.2_12-b01-FCS) for context '/admin-console' 16:26:42,362 INFO [TomcatDeployment] deploy, ctxPath=/ 16:26:42,406 INFO [TomcatDeployment] deploy, ctxPath=/jmx-console 16:26:42,471 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8080 16:26:42,487 INFO [AjpProtocol] Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009 16:26:42,493 INFO [ServerImpl] JBoss (Microcontainer) [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 52s:427ms
在項目資源管理器窗口中選擇EjbComponent項目 Select EjbComponent project in Project Explorer window.
右鍵點擊它,打開上下文菜單。 Right click on it to open context menu.
選擇部署。 Select Deploy.
你會看到在NetBeans控制臺輸出以下內(nèi)容。
ant -f C:EJBEjbComponent -DforceRedeploy=true -Ddirectory.deployment.supported=false -Dnb.wait.for.caches=true run init: deps-jar: compile: library-inclusion-in-archive: Building jar: C:EJBEjbComponentdistEjbComponent.jar dist-directory-deploy: pre-run-deploy: Checking data source definitions for missing JDBC drivers... Distributing C:EJBEjbComponentdistEjbComponent.jar to [org.jboss.deployment.spi.LocalhostTarget@1e4f84ee] Deploying C:EJBEjbComponentdistEjbComponent.jar Applicaton Deployed Operation start started Operation start completed post-run-deploy: run-deploy: run: BUILD SUCCESSFUL (total time: 2 seconds)
JBoss應(yīng)用服務(wù)器日志輸出
16:30:00,963 INFO [DeployHandler] Begin start, [EjbComponent.jar] ... 16:30:01,233 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@12038795{vfszip:/C:/jboss-5.1.0.GA/server/default/deploy/EjbComponent.jar/} ... 16:30:01,281 INFO [JBossASKernel] jndi:LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote 16:30:01,281 INFO [JBossASKernel] Class:com.tutorialspoint.stateless.LibrarySessionBeanRemote 16:30:01,281 INFO [JBossASKernel] jndi:LibrarySessionBean/remote 16:30:01,281 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=EjbComponent.jar,name= LibrarySessionBean,service=EJB3) to KernelDeployment of: EjbComponent.jar 16:30:01,282 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=EjbComponent.jar,name=BookMessageHandler,service=EJB3 16:30:01,282 INFO [JBossASKernel] with dependencies: 16:30:01,282 INFO [JBossASKernel] and demands: 16:30:01,282 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService ... 16:30:01,283 INFO [EJB3EndpointDeployer] Deploy AbstractBeanMetaData@5497cb{name=jboss.j2ee:jar=EjbComponent.jar, name=LibrarySessionBean, service=EJB3_endpoint bean=org.jboss.ejb3.endpoint.deployers.impl.EndpointImpl properties=[container] constructor=null autowireCandidate=true} ... 16:30:01,394 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3 16:30:01,395 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean 16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibrarySessionBean/remote - EJB3.x Default Remote Business Interface LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface 16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3 16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean 16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibrarySessionBean/remote - EJB3.x Default Remote Business Interface LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
在NetBeans IDE中,選擇文件>新建項目> File > New Project >。
在類別中選擇項目類型,Java ,項目類型為Java應(yīng)用程序 Java Application。單擊下一步> Next >
按鈕。
輸入項目名稱和位置。單擊Finish>按鈕。我們選擇的名稱為EjbTester。
右鍵點擊Project Explorer窗口中的項目名稱。選擇屬性 properties。
添加使用編譯compile選項卡中添加項目按鈕創(chuàng)建EJB組件項目。Add ejb component project created earlier under libraries using Add Project button in compile tab.
使用編譯compile選項卡中添加JAR /文件夾按鈕添加的JBoss庫。 Jboss的庫可以位于<JBoss安裝文件夾>>客戶端文件夾 <jboss installation folder>> client folder.
在項目中創(chuàng)建jndi.properties說明EjbTester。
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost
其下創(chuàng)建包com.tutorialspoint.test和EJBTester.java類。
EJBTester.java
package com.tutorialspoint.test; import com.tutorialspoint.stateless.LibrarySessionBeanRemote; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; public class EJBTester { BufferedReader brConsoleReader = null; Properties props; InitialContext ctx; { props = new Properties(); try { props.load(new FileInputStream("jndi.properties")); } catch (IOException ex) { ex.printStackTrace(); } try { ctx = new InitialContext(props); } catch (NamingException ex) { ex.printStackTrace(); } brConsoleReader = new BufferedReader(new InputStreamReader(System.in)); } public static void main(String[] args) { EJBTester ejbTester = new EJBTester(); ejbTester.testStatelessEjb(); } private void showGUI(){ System.out.println("**********************"); System.out.println("Welcome to Book Store"); System.out.println("**********************"); System.out.print("Options 1. Add Book 2. Exit Enter Choice: "); } private void testStatelessEjb(){ try { int choice = 1; LibrarySessionBeanRemote libraryBean = (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote"); while (choice != 2) { String bookName; showGUI(); String strChoice = brConsoleReader.readLine(); choice = Integer.parseInt(strChoice); if (choice == 1) { System.out.print("Enter book name: "); bookName = brConsoleReader.readLine(); libraryBean.addBook(bookName); }else if (choice == 2) { break; } } List<String> booksList = libraryBean.getBooks(); System.out.println("Book(s) entered so far: " + booksList.size()); for (int i = 0; i < booksList.size(); ++i) { System.out.println((i+1)+". " + booksList.get(i)); } LibrarySessionBeanRemote libraryBean1 = (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote"); List<String> booksList1 = libraryBean1.getBooks(); System.out.println( "***Using second lookup to get library stateless object***"); System.out.println( "Book(s) entered so far: " + booksList1.size()); for (int i = 0; i < booksList1.size(); ++i) { System.out.println((i+1)+". " + booksList1.get(i)); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }finally { try { if(brConsoleReader !=null){ brConsoleReader.close(); } } catch (IOException ex) { System.out.println(ex.getMessage()); } } } }
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證Netbeans的控制臺下面的輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 1 Enter book name: Learn Java ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 1 1. Learn Java ***Using second lookup to get library stateless object*** Book(s) entered so far: 0 BUILD SUCCESSFUL (total time: 13 seconds)
在下面的章節(jié)中,我們將討論完整的EJB應(yīng)用程序的多個方面。
無狀態(tài)會話bean是一種企業(yè)bean,它通常用來做獨立操作。無狀態(tài)會話Bean根據(jù)其名字沒有任何關(guān)聯(lián)的客戶端的狀態(tài),但它可能會保留其實例的狀態(tài)。 EJB容器通常會創(chuàng)建一些無狀態(tài)Bean的對象池,并使用這些對象來處理客戶端的請求。由于池,實例變量的值不能保證是相同的跨越查找/方法調(diào)用。
下面是創(chuàng)建一個無狀態(tài)EJB所需的步驟。
創(chuàng)建遠(yuǎn)程/本地接口公開的業(yè)務(wù)方法。 Create a remote/local interface exposing the business methods.
該接口將由EJB客戶端應(yīng)用程序使用。 This interface will be used by the ejb client application.
如果 ejb 客戶端是在相同的環(huán)境中還可以使用 @Local 注釋哪里要部署 ejb 會話 bean。 Use @Local annotation if ejb client is in same environment where ejb session bean is to be deployed.
如果 ejb 客戶端是在不同的環(huán)境中還可以使用 @Remote 注釋哪里要部署 ejb 會話 bean。 Use @Remote annotation if ejb client is in different environment where ejb session bean is to be deployed.
創(chuàng)建一個無狀態(tài)會話bean實現(xiàn)上述接口。 Create a stateless session bean implementing the above interface.
使用 @Stateless annotation注釋來表示它的無狀態(tài) bean。EJB 容器會自動創(chuàng)建有關(guān)的配置或通過閱讀此批注在部署過程中的所需的接口。 Use @Stateless annotation to signify it a stateless bean. EJB Container automatically creates the relevant configurations or interfaces required by reading this annotation during deployment.
遠(yuǎn)程接口
import javax.ejb.Remote; @Remote public interface LibrarySessionBeanRemote { //add business method declarations }
無狀態(tài)EJB
@Stateless public class LibrarySessionBean implements LibrarySessionBeanRemote { //implement business method }
讓我們創(chuàng)建一個測試EJB應(yīng)用程序來測試無狀態(tài)EJB。
步驟 | 描述 |
---|---|
1 | 用包com.tutorialspoint.stateless下一個名字EjbComponent在EJB作為解釋的創(chuàng)建項目-創(chuàng)建應(yīng)用程序一章。您也可以使用EJB創(chuàng)建的項目-創(chuàng)建應(yīng)用程序章這樣本章了解無狀態(tài)的EJB概念。 |
2 | 創(chuàng)建LibrarySessionBean.java和LibrarySessionBeanRemote作為EJB解釋-創(chuàng)建應(yīng)用程序一章。保持不變的文件其余部分。 |
3 | 清理并生成應(yīng)用程序,確保業(yè)務(wù)邏輯正在按要求。 |
4 | 最后,部署JBoss應(yīng)用服務(wù)器上的jar文件的形式應(yīng)用。如果尚未啟動JBoss應(yīng)用服務(wù)器將自動被啟動。 |
5 | 現(xiàn)在創(chuàng)建EJB客戶端,以同樣的方式一個基于控制臺的應(yīng)用程序在EJB解釋-創(chuàng)建應(yīng)用程序一章的主題創(chuàng)建客戶機訪問EJB。 |
package com.tutorialspoint.stateless; import java.util.List; import javax.ejb.Remote; @Remote public interface LibrarySessionBeanRemote { void addBook(String bookName); List getBooks(); }
package com.tutorialspoint.stateless; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateless; @Stateless public class LibrarySessionBean implements LibrarySessionBeanRemote { List<String> bookShelf; public LibrarySessionBean(){ bookShelf = new ArrayList<String>(); } public void addBook(String bookName) { bookShelf.add(bookName); } public List<String> getBooks() { return bookShelf; } }
一旦你部署EjbComponent項目到JBoss上,注意jboss的日志。
JBoss已經(jīng)具備自動創(chuàng)建我們的會話bean JNDI入口- LibrarySessionBean /remote。
我們將使用此查找字符串來獲取遠(yuǎn)程業(yè)務(wù)對象的類型- com.tutorialspoint.stateless.LibrarySessionBeanRemote
... 16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibrarySessionBean/remote - EJB3.x Default Remote Business Interface LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface 16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3 16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibrarySessionBean 16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibrarySessionBean/remote - EJB3.x Default Remote Business Interface LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface ...
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost
這些屬性用于初始化Java命名服務(wù)的InitialContext對象
InitialContext對象將被用于查找無狀態(tài)會話bean
package com.tutorialspoint.test; import com.tutorialspoint.stateful.LibrarySessionBeanRemote; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; public class EJBTester { BufferedReader brConsoleReader = null; Properties props; InitialContext ctx; { props = new Properties(); try { props.load(new FileInputStream("jndi.properties")); } catch (IOException ex) { ex.printStackTrace(); } try { ctx = new InitialContext(props); } catch (NamingException ex) { ex.printStackTrace(); } brConsoleReader = new BufferedReader(new InputStreamReader(System.in)); } public static void main(String[] args) { EJBTester ejbTester = new EJBTester(); ejbTester.testStatelessEjb(); } private void showGUI(){ System.out.println("**********************"); System.out.println("Welcome to Book Store"); System.out.println("**********************"); System.out.print("Options 1. Add Book 2. Exit Enter Choice: "); } private void testStatelessEjb(){ try { int choice = 1; LibrarySessionBeanRemote libraryBean = LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote"); while (choice != 2) { String bookName; showGUI(); String strChoice = brConsoleReader.readLine(); choice = Integer.parseInt(strChoice); if (choice == 1) { System.out.print("Enter book name: "); bookName = brConsoleReader.readLine(); Book book = new Book(); book.setName(bookName); libraryBean.addBook(book); } else if (choice == 2) { break; } } List<Book> booksList = libraryBean.getBooks(); System.out.println("Book(s) entered so far: " + booksList.size()); int i = 0; for (Book book:booksList) { System.out.println((i+1)+". " + book.getName()); i++; } LibrarySessionBeanRemote libraryBean1 = (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote"); List<String> booksList1 = libraryBean1.getBooks(); System.out.println( "***Using second lookup to get library stateless object***"); System.out.println( "Book(s) entered so far: " + booksList1.size()); for (int i = 0; i < booksList1.size(); ++i) { System.out.println((i+1)+". " + booksList1.get(i)); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }finally { try { if(brConsoleReader !=null){ brConsoleReader.close(); } } catch (IOException ex) { System.out.println(ex.getMessage()); } } } }
EJBTester執(zhí)行以下任務(wù)。
從 jndi.properties 加載屬性并初始化輸出對象。
在testStatelessEjb()方法中,jndi查找名稱——“LibrarySessionBean /remote”來獲取遠(yuǎn)程業(yè)務(wù)對象(無狀態(tài)ejb)。
然后用戶顯示庫存儲用戶界面和他(她)被要求輸入選擇。
如果用戶輸入1,系統(tǒng)要求書名并保存使用無狀態(tài)會話bean addBook()方法的書。會話bean存儲本書的實例變量。
如果用戶輸入2,系統(tǒng)檢索使用無狀態(tài)會話bean getBooks()方法,并退出書籍。
完成另一個jndi查找名稱——“LibrarySessionBean /remote”來獲取遠(yuǎn)程業(yè)務(wù)對象(無狀態(tài)ejb)和清單的書。
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 1 Enter book name: Learn Java ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 1 1. Learn Java ***Using second lookup to get library stateless object*** Book(s) entered so far: 0 BUILD SUCCESSFUL (total time: 13 seconds)
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 0 ***Using second lookup to get library stateless object*** Book(s) entered so far: 1 1. Learn Java BUILD SUCCESSFUL (total time: 12 seconds)
上面顯示的輸出可能會有所不同取決于JBoss保持多少的無狀態(tài)的EJB對象。Output shown above may vary depending upon how many stateless ejb object JBoss is maintaining.
如果一個無狀態(tài)的EJB對象保持不變,則可能每個查找后,看到相同的書籍列表。In case a single stateless ejb object is maintained, you may see the same list of books after each lookup.
EJB 容器于每個查找可能會返回相同的無狀態(tài) ejb 對象。EJB Container may return same stateless ejb object for every lookup.
無狀態(tài) ejb bean 保持實例變量的值,直到不重新啟動服務(wù)器。Stateless ejb bean is keeping value of instance variable till the server is not restarted.
有狀態(tài)會話bean是一種企業(yè)bean保存會話狀態(tài)與客戶端。有狀態(tài)會話bean按照其名稱讓相關(guān)客戶端狀態(tài)的實例變量。EJB容器創(chuàng)建一個單獨的有狀態(tài)會話bean來處理客戶的每個請求。一旦請求范圍結(jié)束,statelful會話bean被摧毀。
下面是創(chuàng)建一個有狀態(tài)EJB所需的步驟。
創(chuàng)建遠(yuǎn)程/本地接口公開的業(yè)務(wù)方法。
該接口將由EJB客戶端應(yīng)用程序使用。
如果 ejb 客戶端是在相同的環(huán)境中還可以使用 @Local 注釋哪里要部署 ejb 會話 bean。
如果 ejb 客戶端是在不同的環(huán)境中還可以使用 @Remote 注釋哪里要部署 ejb 會話 bean。
創(chuàng)建有狀態(tài)會話bean執(zhí)行上述接口。
使用 @Stateful 注釋來表示它有狀態(tài)會話 bean。EJB 容器會自動創(chuàng)建有關(guān)的配置或通過閱讀此批注在部署過程中的所需的接口。
遠(yuǎn)程接口
import javax.ejb.Remote; @Remote public interface LibraryStatefulSessionBeanRemote { //add business method declarations }
EJB狀態(tài)
@Stateful public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote { //implement business method }
讓我們創(chuàng)建一個測試EJB應(yīng)用程序來測試狀態(tài)EJB。
步驟 | 描述 |
---|---|
1 | 創(chuàng)建一個包com.tutorialspoint.stateful下一個名字EjbComponent項目作為EJB解釋-創(chuàng)建應(yīng)用程序一章。您也可以使用EJB創(chuàng)建的項目-創(chuàng)建應(yīng)用程序章這樣本章了解狀態(tài)EJB概念。 |
2 | 創(chuàng)建LibraryStatefulSessionBean.java和LibraryStatefulSessionBeanRemote作為EJB解釋-創(chuàng)建應(yīng)用程序一章。保持不變的文件其余部分。 |
3 | 清理并生成應(yīng)用程序,確保業(yè)務(wù)邏輯正在按要求。 |
4 | 最后,部署JBoss應(yīng)用服務(wù)器上的jar文件的形式應(yīng)用。如果尚未啟動JBoss應(yīng)用服務(wù)器將自動被啟動。 |
5 | 現(xiàn)在創(chuàng)建EJB客戶端,以同樣的方式一個基于控制臺的應(yīng)用程序在EJB解釋-創(chuàng)建應(yīng)用程序一章的主題創(chuàng)建客戶機訪問EJB。 |
package com.tutorialspoint.stateful; import java.util.List; import javax.ejb.Remote; @Remote public interface LibraryStatefulSessionBeanRemote { void addBook(String bookName); List getBooks(); }
package com.tutorialspoint.stateful; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateful; @Stateful public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote { List<String> bookShelf; public LibraryStatefulSessionBean(){ bookShelf = new ArrayList<String>(); } public void addBook(String bookName) { bookShelf.add(bookName); } public List<String> getBooks() { return bookShelf; } }
一旦你部署EjbComponent項目到JBoss上,注意jboss的日志。
JJBoss已經(jīng)自動創(chuàng)建一個JNDI條目- LibraryStatefulSessionBean /remote。
我們將使用這個查詢字符串獲取遠(yuǎn)程業(yè)務(wù)類型的對象- com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote
... 16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface 16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryStatefulSessionBean,service=EJB3 16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote ejbName: LibraryStatefulSessionBean 16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface ...
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost
這些屬性用于初始化Java命名服務(wù)的InitialContext對象
InitialContext對象將被用于查找有狀態(tài)會話Bean
package com.tutorialspoint.test; import com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; public class EJBTester { BufferedReader brConsoleReader = null; Properties props; InitialContext ctx; { props = new Properties(); try { props.load(new FileInputStream("jndi.properties")); } catch (IOException ex) { ex.printStackTrace(); } try { ctx = new InitialContext(props); } catch (NamingException ex) { ex.printStackTrace(); } brConsoleReader = new BufferedReader(new InputStreamReader(System.in)); } public static void main(String[] args) { EJBTester ejbTester = new EJBTester(); ejbTester.testStatelessEjb(); } private void showGUI(){ System.out.println("**********************"); System.out.println("Welcome to Book Store"); System.out.println("**********************"); System.out.print("Options 1. Add Book 2. Exit Enter Choice: "); } private void testStatelessEjb(){ try { int choice = 1; LibraryStatefulSessionBeanRemote libraryBean = LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote"); while (choice != 2) { String bookName; showGUI(); String strChoice = brConsoleReader.readLine(); choice = Integer.parseInt(strChoice); if (choice == 1) { System.out.print("Enter book name: "); bookName = brConsoleReader.readLine(); Book book = new Book(); book.setName(bookName); libraryBean.addBook(book); } else if (choice == 2) { break; } } List<Book> booksList = libraryBean.getBooks(); System.out.println("Book(s) entered so far: " + booksList.size()); int i = 0; for (Book book:booksList) { System.out.println((i+1)+". " + book.getName()); i++; } LibraryStatefulSessionBeanRemote libraryBean1 = (LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote"); List<String> booksList1 = libraryBean1.getBooks(); System.out.println( "***Using second lookup to get library stateful object***"); System.out.println( "Book(s) entered so far: " + booksList1.size()); for (int i = 0; i < booksList1.size(); ++i) { System.out.println((i+1)+". " + booksList1.get(i)); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }finally { try { if(brConsoleReader !=null){ brConsoleReader.close(); } } catch (IOException ex) { System.out.println(ex.getMessage()); } } } }
EJBTester執(zhí)行以下任務(wù)。
從 jndi.properties 加載屬性并初始化輸出對象。
在testStatefulEjb()方法中,jndi查找名稱——“LibraryStatefulSessionBean /remote”來獲取遠(yuǎn)程業(yè)務(wù)對象(有狀態(tài)的ejb)。
然后用戶顯示的用戶界面庫存儲和他/她被要求輸入選擇。
如果用戶輸入 1,系統(tǒng)將要求書名稱并保存使用有狀態(tài)會話 bean addBook() 方法的書。會話 Bean 在它的實例變量中存儲這本書。
如果用戶輸入2,系統(tǒng)檢索圖書使用有狀態(tài)會話bean getBooks()方法并退出。
完成另一個jndi查找名稱——“LibraryStatefulSessionBean /遠(yuǎn)程”來獲取遠(yuǎn)程業(yè)務(wù)對象(有狀態(tài)的ejb)和清單的書。
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 1 Enter book name: Learn Java ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 1 1. Learn Java ***Using second lookup to get library stateful object*** Book(s) entered so far: 0 BUILD SUCCESSFUL (total time: 13 seconds)
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 0 ***Using second lookup to get library stateful object*** Book(s) entered so far: 0 BUILD SUCCESSFUL (total time: 12 seconds)
上面顯示輸出狀態(tài),對于每個查找返回不同的狀態(tài)EJB實例。
有狀態(tài)EJB對象是保持只單個會話值。正如在第二次運行,我們沒有得到圖書的任何值。
EJB 3.0實體bean中使用EJB 2.0在很大程度上是被持久性機制所取代。現(xiàn)在實體bean是一個簡單的POJO映射表。
以下是持久性API的關(guān)鍵角色
實體 Entity-代表數(shù)據(jù)存儲記錄持久對象。這是好事,可序列化。
EntityManager -持久性接口進行數(shù)據(jù)操作,如添加/刪除/更新/查找持久化對象(實體)上。它還有助于使用查詢界面來執(zhí)行查詢。
持久性單元 Persistence unit(persistence.xml) -持久性單元描述持久化機制的屬性。
數(shù)據(jù)源 Data Source(* ds.xml中) -數(shù)據(jù)源介紹像連接URL的數(shù)據(jù)存儲相關(guān)的屬性。用戶名,密碼等。
為了展示EJB的持久性機制,我們將執(zhí)行以下任務(wù)。
第1步:在數(shù)據(jù)庫中創(chuàng)建表。
第2步:創(chuàng)建對應(yīng)表的實體類。
第3步:創(chuàng)建數(shù)據(jù)源和持久性單元
第4步:創(chuàng)建具有EntityManager實例的無狀態(tài)EJB。
第5步:更新無狀態(tài)EJB。添加的方法來添加記錄,并通過實體管理器獲得數(shù)據(jù)庫記錄。
第6步:基于控制臺應(yīng)用程序的客戶端將訪問無狀態(tài)EJB在數(shù)據(jù)庫中留存的數(shù)據(jù)。
在默認(rèn)數(shù)據(jù)庫 postgres 中創(chuàng)建書的表。
CREATE TABLE books ( id integer PRIMARY KEY, name varchar(50) );
//mark it entity using Entity annotation //map table name using Table annoation @Entity @Table(name="books") public class Book implements Serializable{ private int id; private String name; public Book(){ } //mark id as primary key with autogenerated value //map database column id with id field @Id @GeneratedValue(strategy= GenerationType.IDENTITY) @Column(name="id") public int getId() { return id; } ... }
數(shù)據(jù)源(jboss-ds.xml)
<?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>PostgresDS</jndi-name> <connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url> <driver-class>org.postgresql.driver</driver-class> <user-name>sa</user-name> <password>sa</password> <min-pool-size>5</min-pool-size> <max-pool-size>20</max-pool-size> <idle-timeout-minutes>5</idle-timeout-minutes> </local-tx-datasource> </datasources>
持久性單元(persistence.xml中)
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="EjbComponentPU" transaction-type="JTA"> <jta-data-source>java:/PostgresDS</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties/> </persistence-unit> <persistence-unit name="EjbComponentPU2" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/PostgresDS</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
@Stateless public class LibraryPersistentBean implements LibraryPersistentBeanRemote { //pass persistence unit to entityManager. @PersistenceContext(unitName="EjbComponentPU") private EntityManager entityManager; public void addBook(Book book) { entityManager.persist(book); } public List<Book> getBooks() { return entityManager.createQuery("From Books").getResultList(); } ... }
構(gòu)建EJB模塊之后,我們需要一個客戶端訪問bean的無狀態(tài),我們會在下一節(jié)中創(chuàng)建。
讓我們創(chuàng)建一個測試EJB應(yīng)用程序來測試EJB的持久性機制。
步驟 | 描述 |
---|---|
1 | 用包com.tutorialspoint.entity下一個名字EjbComponent在EJB作為解釋的創(chuàng)建項目-創(chuàng)建應(yīng)用程序一章。您也可以使用EJB創(chuàng)建的項目-創(chuàng)建應(yīng)用程序章這樣本章了解EJB的持久性概念。 |
2 | 包下com.tutorialspoint.entity創(chuàng)建Book.java,并修改它,如下圖所示。 |
3 | 創(chuàng)建LibraryPersistentBean.java和LibraryPersistentBeanRemote作為EJB解釋-創(chuàng)建應(yīng)用程序一章并修改它們,如下圖所示。 |
4 | 創(chuàng)建EjbComponent>在EjbComponent>來源> conf文件夾安裝文件夾和persistence.xml中 的jboss-ds.xml文件 。這些文件夾可以在Netbeans的文件選項卡中可以看出。修改這些文件,如上圖所示。 |
6 | 清理并生成應(yīng)用程序,確保業(yè)務(wù)邏輯正在按要求。 |
6 | 最后,部署JBoss應(yīng)用服務(wù)器上的jar文件的形式應(yīng)用。如果尚未啟動JBoss應(yīng)用服務(wù)器將自動被啟動。 |
7 | 現(xiàn)在創(chuàng)建EJB客戶端,以同樣的方式一個基于控制臺的應(yīng)用程序在EJB解釋-創(chuàng)建應(yīng)用程序一章的主題創(chuàng)建客戶機訪問EJB。修改它,如下圖所示。 |
package com.tutorialspoint.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityListeners; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="books") public class Book implements Serializable{ private int id; private String name; public Book(){ } @Id @GeneratedValue(strategy= GenerationType.IDENTITY) @Column(name="id") public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.tutorialspoint.stateless; import com.tutorialspoint.entity.Book; import java.util.List; import javax.ejb.Remote; @Remote public interface LibraryPersistentBeanRemote { void addBook(Book bookName); List<Book> getBooks(); }
package com.tutorialspoint.stateless; import com.tutorialspoint.entity.Book; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @Stateless public class LibraryPersistentBean implements LibraryPersistentBeanRemote { public LibraryPersistentBean(){ } @PersistenceContext(unitName="EjbComponentPU") private EntityManager entityManager; public void addBook(Book book) { entityManager.persist(book); } public List<Book> getBooks() { return entityManager.createQuery("From Book").getResultList(); } }
一旦你部署EjbComponent項目到JBoss上,注意jboss的日志。
JBoss已經(jīng)自動創(chuàng)建一個JNDI條目-LibraryPersistentBean/remote.
我們將使用這個查詢字符串獲取遠(yuǎn)程業(yè)務(wù)類型的對象- com.tutorialspoint.stateless.LibraryPersistentBeanRemote
... 16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface 16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3 16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean 16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface ...
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost
這些屬性用于初始化Java命名服務(wù)的InitialContext對象
InitialContext對象將被用于查找無狀態(tài)會話bean
package com.tutorialspoint.test; import com.tutorialspoint.stateless.LibraryPersistentBeanRemote; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; public class EJBTester { BufferedReader brConsoleReader = null; Properties props; InitialContext ctx; { props = new Properties(); try { props.load(new FileInputStream("jndi.properties")); } catch (IOException ex) { ex.printStackTrace(); } try { ctx = new InitialContext(props); } catch (NamingException ex) { ex.printStackTrace(); } brConsoleReader = new BufferedReader(new InputStreamReader(System.in)); } public static void main(String[] args) { EJBTester ejbTester = new EJBTester(); ejbTester.testEntityEjb(); } private void showGUI(){ System.out.println("**********************"); System.out.println("Welcome to Book Store"); System.out.println("**********************"); System.out.print("Options 1. Add Book 2. Exit Enter Choice: "); } private void testEntityEjb(){ try { int choice = 1; LibraryPersistentBeanRemote libraryBean = LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote"); while (choice != 2) { String bookName; showGUI(); String strChoice = brConsoleReader.readLine(); choice = Integer.parseInt(strChoice); if (choice == 1) { System.out.print("Enter book name: "); bookName = brConsoleReader.readLine(); Book book = new Book(); book.setName(bookName); libraryBean.addBook(book); } else if (choice == 2) { break; } } List<Book> booksList = libraryBean.getBooks(); System.out.println("Book(s) entered so far: " + booksList.size()); int i = 0; for (Book book:booksList) { System.out.println((i+1)+". " + book.getName()); i++; } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }finally { try { if(brConsoleReader !=null){ brConsoleReader.close(); } } catch (IOException ex) { System.out.println(ex.getMessage()); } } } }
EJBTester執(zhí)行以下任務(wù)。
從 jndi.properties 加載屬性并初始化輸出對象。
在testStatefulEjb()方法中,jndi查找名稱——“LibraryStatefulSessionBean /remote”來獲取遠(yuǎn)程業(yè)務(wù)對象(有狀態(tài)的ejb)。
然后用戶顯示庫存儲用戶界面和他(她)被要求輸入選擇。
如果用戶輸入 1,系統(tǒng)將要求書名稱并保存使用無狀態(tài)會話 bean addBook() 方法的書。會話 Bean 堅持通過實體管理器調(diào)用數(shù)據(jù)庫中的書。
如果用戶輸入2,系統(tǒng)檢索圖書使用有狀態(tài)會話bean getBooks()方法并退出。
完成另一個jndi查找名稱——“LibraryStatelessSessionBean /遠(yuǎn)程”來獲取遠(yuǎn)程業(yè)務(wù)對象(無狀態(tài)ejb)和清單的書。
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 1 Enter book name: Learn Java ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 1 1. learn java BUILD SUCCESSFUL (total time: 15 seconds)
訪問EJB之前重新啟動JBoss。
在項目資源管理器中找到EJBTester.java。右鍵單擊EJBTester類并選擇運行文件 run file。
驗證以下在 Netbeans 控制臺輸出。
run: ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 1 Enter book name: Learn Spring ********************** Welcome to Book Store ********************** Options 1. Add Book 2. Exit Enter Choice: 2 Book(s) entered so far: 2 1. learn java 2. Learn Spring BUILD SUCCESSFUL (total time: 15 seconds)
上面顯示的輸出表明,書籍存儲在持久性存儲中,并從數(shù)據(jù)庫中檢索到。
消息驅(qū)動的bean是一種企業(yè)bean調(diào)用的EJB容器時,它接收一條消息隊列或主題。消息驅(qū)動的bean是一個無狀態(tài)bean,用于做異步任務(wù)。
為了演示使用消息驅(qū)動bean,我們將使用EJB的持久性這一章,我們要做以下工作。
步驟1.創(chuàng)建數(shù)據(jù)庫表(參見EJB的持久性這一章)。
步驟2.創(chuàng)建實體類對應(yīng)表(參見EJB的持久性這一章)。
步驟3.創(chuàng)建數(shù)據(jù)源和持久性單元(參見EJB的持久性這一章)。
步驟4.創(chuàng)建一個無狀態(tài)EJB EntityManager實例(參見EJB的持久性這一章)。
步驟5:更新無狀態(tài)ejb。添加方法添加記錄,記錄從數(shù)據(jù)庫通過實體管理器(指的EJB持久性這一章)。
步驟6:創(chuàng)建一個名為BookQueue的隊列在JBoss默認(rèn)應(yīng)用程序目錄中。
步驟7:基于控制臺應(yīng)用程序的客戶端會發(fā)送消息到這個隊列中。
步驟8:創(chuàng)建一個消息驅(qū)動的bean將使用無狀態(tài)bean保存客戶數(shù)據(jù)。
步驟9:的JBoss的EJB容器將調(diào)用上述消息驅(qū)動bean并將它傳遞客戶端將被發(fā)送到郵件中。
Create a file named jbossmq-destinations-service.xml if not exists in <JBoss Installation Folder> > server > default > deploy folder.
在這里,我們創(chuàng)建了一個名為BookQueue隊列
jbossmq-destinations-service.xml
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=BookQueue"> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean>
當(dāng)你啟動JBoss,你會看到一個類似的條目在JBoss日志中
... 10:37:06,167 INFO [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000 ...
@MessageDriven( name = "BookMessageHandler", activationConfig = { @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty( propertyName = "destination", propertyValue ="/queue/BookQueue") } ) public class LibraryMessageBean implements MessageListener { @Resource private MessageDrivenContext mdctx; @EJB LibraryPersistentBeanRemote libraryBean; public LibraryMessageBean(){ } public void onMessage(Message message) { } }
LibraryMessageBean與@MessageDriven annoatated將其標(biāo)記為消息驅(qū)動bean。
其性質(zhì)被定義為destinationType - 隊列和目的地 - /queue/ BookQueue。
它實現(xiàn)了MessageListener接口公開消息的方法。
它有 MessgeDrivenContext 作為資源。
LibraryPersistentBeanRemote 無狀態(tài) bean 被注射在此 bean為了持久性的目的。
構(gòu)建EjbComponent項目,并在JBoss部署它。構(gòu)建和部署EJB模塊后,我們需要一個客戶端發(fā)送消息到JBoss隊列。
讓我們創(chuàng)建一個測試 EJB 應(yīng)用程序來測試消息驅(qū)動 Bean。
步驟 | 描述 |
---|---|
1 | 用包com.tutorialspoint.entity下一個名字EjbComponent在EJB作為解釋的創(chuàng)建項目-創(chuàng)建應(yīng)用程序一章。您也可以使用EJB創(chuàng)建的項目-創(chuàng)建應(yīng)用程序章這樣本章了解EJB的持久性概念。 |
2 | 包下com.tutorialspoint.entity創(chuàng)建Book.java作為EJB的持久性創(chuàng)建章 |
3 | 創(chuàng)建LibraryPersistentBean.java和LibraryPersistentBeanRemote作為EJB的持久性創(chuàng)建章 |
4 | 創(chuàng)建EjbComponent>在EjbComponent>來源> conf文件夾安裝文件夾和persistence.xml中 的jboss-ds.xml文件 。這些文件夾可在文件選項卡中可以看出在Netbeans的作為EJB的持久性創(chuàng)建章 |
5 | 包com.tutorialspoint.messagebean下創(chuàng)建LibraryMessageBean.java,并修改它,如下圖所示。 |
6 | 在JBoss中創(chuàng)建BookQueue隊列如上所述。 |
7 | 清理并生成應(yīng)用程序,確保業(yè)務(wù)邏輯正在按要求。 |
更多建議: