EJB快速指南

2018-12-12 15:00 更新

EJB - 概述

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ōu)點

  • 簡化大型企業(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 - 環(huán)境設(shè)置

EJB是Java的框架,因此第一個要求是JDK已經(jīng)安裝在你的機器上。

系統(tǒng)需求

JDK1.5或以上。
Memory
內(nèi)存
沒有最低要求。
Disk Space
磁盤空間
沒有最低要求。
Operating System
操作系統(tǒng)
沒有最低要求。


第1步 - 驗證Java安裝在你的機器上

現(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作為安裝版本。


第2步:設(shè)置Java環(huán)境

設(shè)置JAVA_HOME環(huán)境變量,使之指向安裝在您機器上Java的基本目錄位置。例如

OS產(chǎn)量
Windows環(huán)境變量JAVA_HOME設(shè)置為C:\Program Files\Java\jdk1.6.0_21
Linuxexport JAVA_HOME=/usr/local/java-current
Macexport JAVA_HOME=/Library/Java/Home


將 Java 編譯器位置追加系統(tǒng)路徑

OS產(chǎn)量
Windows追加字符串;C:\Program Files\Java\jdk1.6.0_21in 系統(tǒng)變量,路徑末尾
Linuxexport PATH=$PATH:$JAVA_HOME/bin/
Mac不需要

使用Java - version命令驗證如上所述安裝的Java。


第3步:下載并安裝NetBeans IDE

下載最新版本的NetBeans IDEhttps://netbeans.org/downloads/index.html 。在寫這篇教程的時候,我下載Netbeans 7.3里面自帶JDK 1.7捆綁在一起。使用以下鏈接http://www.oracle.com/technetwork/java/javase/downloads/index.html

OS安裝程序名稱
WindowsNetbeans  7.3
LinuxNetbeans  7.3
MacNetbeans  7.3


第4步:安裝JBoss應(yīng)用服務(wù)器:

您可以下載最新版本的JBoss服務(wù)器http://www.jboss.org/jbossas/downloads/ 。根據(jù)下OS下載對應(yīng)的檔案。提取Jboss到你機器上的任意位置。

OS文件名
Windowsjboss-5.1.0.GA-jdk6.zip
Linux的jboss-5.1.0.GA-src.tar.gz
Mac的jboss-5.1.0.GA-src.tar.gz


步驟5:配置JEE插件的Netbeans

打開插件窗口使用工具 > 插件。打開"可用插件"標(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.

已安裝的插件


步驟6:配置Netbeans中的JBoss服務(wù)器

轉(zhuǎn)到服務(wù)選項卡,并用鼠標(biāo)右鍵單擊服務(wù)器來添加新的服務(wù)器。

Go to Services tab and right click on servers to add a new server.


添加服務(wù)器

添加服務(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.


選擇服務(wù)器

一旦一切都cofigured,你會看到以下畫面。


安裝的服務(wù)器


第7步:安裝數(shù)據(jù)庫服務(wù)器(PostgreSQL系統(tǒng))。

下載最新版本的PostgreSQL數(shù)據(jù)庫服務(wù)器http://www.postgresql.org/download/ 。本教程下載的是PostgreSQL 9.2

OS安裝程序名稱
WindowsPostgreSQL  9.2
LinuxPostgreSQL  9.2
MacPostgreSQL  9.2


EJB - 創(chuàng)建應(yīng)用程序

若要創(chuàng)建一個簡單的 EJB 模塊,我們將使用 NetBeans"新建項目"向?qū)?/span>。以下示例我們將創(chuàng)建一個名為Component的 ejb 模塊項目。

創(chuàng)建項目

在NetBeans IDE中,選擇File > New Project >  文件>新建項目>。你會看到以下畫面。


新建項目向?qū)У牟襟E1


選擇項目類型,Java EE 項目類別作為 Ejb 模塊。單擊下一步 > 按鈕您將看到下圖所示的畫面


新建項目向?qū)У牟襟E2


輸入項目名稱和位置。單擊下一步>Next > 按鈕。你會看到以下畫面。


新建項目向?qū)У牟襟E3

選擇服務(wù)器作為JBoss應(yīng)用服務(wù)器 。單擊Finish按鈕。你會看到NetBeans中創(chuàng)建以下項目。


項目資源管理器


創(chuàng)建一個示例EJB

若要創(chuàng)建一個簡單的 EJB,我們會使用 NetBeans"新建"向?qū)?/span>下面示例,我們將創(chuàng)建一個在EjbComponent項目名為librarySessionBean無狀態(tài) ejb 

項目資源管理器窗口選取項目 EjbComponent右鍵點擊。選擇New > Session Bean
 > 會議 Bean.你將會看到會話 Beanwizard。

新建會話Bean向?qū)? style=

輸入會話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;
    }
}


建設(shè)項目

  • 在項目資源管理器窗口中選擇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)


啟動應(yīng)用服務(wù)器

  • 在服務(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
 

創(chuàng)建客戶端訪問EJB

  • 在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());
         }
      }
   }  
}


運行客戶端訪問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)

在下面的章節(jié)中,我們將討論完整的EJB應(yīng)用程序的多個方面。


EJB - 無狀態(tài)Bean

無狀態(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) beanEJB 容器會自動創(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 
}


示例應(yīng)用程序

讓我們創(chuàng)建一個測試EJB應(yīng)用程序來測試無狀態(tài)EJB。

步驟描述
1用包com.tutorialspoint.stateless下一個名字EjbComponentEJB作為解釋的創(chuàng)建項目-創(chuàng)建應(yīng)用程序一章。您也可以使用EJB創(chuàng)建的項目-創(chuàng)建應(yīng)用程序章這樣本章了解無狀態(tài)的EJB概念。
2創(chuàng)建LibrarySessionBean.javaLibrarySessionBeanRemote作為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。


EJBComponent(EJB模塊)

LibrarySessionBeanRemote.java

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}


LibrarySessionBean.java

 
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


JBoss應(yīng)用服務(wù)器日志輸出

...
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
...   


EJBTester(EJB客戶端)

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
  • 這些屬性用于初始化Java命名服務(wù)的InitialContext對象

  • InitialContext對象將被用于查找無狀態(tài)會話bean


EJBTester.java

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)和清單的書。


運行客戶端訪問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)


再次運行客戶端訪問EJB

在項目資源管理器中找到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.


EJB - 狀態(tài)bean

有狀態(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 
}


示例應(yīng)用程序

讓我們創(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.javaLibraryStatefulSessionBeanRemote作為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。


EJBComponent(EJB模塊)

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}


LibraryStatefulSessionBean.java

 
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


JBoss應(yīng)用服務(wù)器日志輸出

...
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
...   


EJBTester(EJB客戶端)

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
  • 這些屬性用于初始化Java命名服務(wù)的InitialContext對象

  • InitialContext對象將被用于查找有狀態(tài)會話Bean


EJBTester.java

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)和清單的書。


運行客戶端訪問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)


再次運行客戶端訪問EJB

在項目資源管理器中找到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 - 持久性

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ù)。


創(chuàng)建表

默認(rèn)數(shù)據(jù)庫 postgres 創(chuàng)建。

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);


創(chuàng)建實體類

//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;
   }
   ...
}


創(chuàng)建數(shù)據(jù)源和持久性單元

數(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>


創(chuàng)建無狀態(tài)EJB EntityManager實例

@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)建。


示例應(yīng)用程序

讓我們創(chuàng)建一個測試EJB應(yīng)用程序來測試EJB的持久性機制。

步驟描述
1用包com.tutorialspoint.entity下一個名字EjbComponentEJB作為解釋的創(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.javaLibraryPersistentBeanRemote作為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。修改它,如下圖所示。


EJBComponent(EJB模塊)

Book.java

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;
   }    
}


LibraryPersistentBeanRemote.java

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();
    
}


LibraryPersistentBean.java

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

JBoss應(yīng)用服務(wù)器日志輸出

...
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
...   


EJBTester(EJB客戶端)

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
  • 這些屬性用于初始化Java命名服務(wù)的InitialContext對象

  • InitialContext對象將被用于查找無狀態(tài)會話bean


EJBTester.java

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)和清單的書。


運行客戶端訪問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。

訪問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ù)庫中檢索到。


EJB - 消息驅(qū)動Bean

消息驅(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ā)送到郵件中。


創(chuàng)建隊列

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
...


創(chuàng)建消息驅(qū)動Bean

@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隊列。


示例應(yīng)用程序

我們創(chuàng)建一個測試 EJB 應(yīng)用程序測試消息驅(qū)動 Bean。

步驟描述
1用包com.tutorialspoint.entity下一個名字EjbComponentEJB作為解釋的創(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.javaLibraryPersistentBeanRemote作為EJB的持久性創(chuàng)建章
4創(chuàng)建EjbComponent>EjbComponent>來源> conf文件夾安裝文件夾和persistence.xml中 的jboss-ds.xml文件 。這些文件夾可在文件選項卡中可以看出在Netbeans的作為EJB的持久性創(chuàng)建章
5com.tutorialspoint.messagebean下創(chuàng)建LibraryMessageBean.java,并修改它,如下圖所示。
6在JBoss中創(chuàng)建BookQueue隊列如上所述。
7清理并生成應(yīng)用程序,確保業(yè)務(wù)邏輯正在按要求。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號