EJB快速指南

2018-12-12 15:00 更新

EJB - 概述

EJB代表企业Java Beans。 EJB是J2EE平台的一个重要组成部分。 J2EE平台拥有基于组件的架构,可提供多层次,分布式和高事务功能的企业级应用。


EJB提供了一个架构来开发和部署考虑稳健性,高可扩展性和高性能的基于组件的企业应用程序。 EJB应用程序可以部署在任何符合J2EE 1.3标准规范的应用服务器上。我们将在本教程中讨论EJB 3.0。


优点

  • 简化大型企业级应用程序的开发。

  • 应用服务器/ EJB容器提供了最像事务处理,日志记录,负载均衡,持久性机制,异常处理等系统级的服务。开发者只需注重于应用程序的业务逻辑。

  • EJB容器管理EJB事例的生命周期,因此开发人员不需要担心何时创建/删除EJB对象


类型

EJB主要的三种类型将在下面进行简要描述:

类型描述

会话Bean

Session Bean

会话bean在单个会话特定用户的存储数据。它可以是有状态或无状态的。相比于实体bean是资源较少。会话bean得到尽快的用户会话终止销毁。

实体Bean

Entity Bean

实体Bean表示持久性数据存储。用户数据可以通过实体bean可以保存到数据库,以后可以从实体bean的数据库中检索。

消息驱动bean

Message Driven Bean

消息驱动Bean在JMS(Java消息服务)的环境中使用。消息驱动Bean可以从外部实体消耗JMS消息,并采取相应的行动。


EJB - 环境设置

EJB是Java的框架,因此第一个要求是JDK已经安装在你的机器上。

系统需求

JDK1.5或以上。
Memory
内存
没有最低要求。
Disk Space
磁盘空间
没有最低要求。
Operating System
操作系统
没有最低要求。


第1步 - 验证Java安装在你的机器上

现在打开控制台并执行以下java命令。

OS任务命令
Windows打开命令控制台C:> Java的版本
Linux打开命令终端$ Java的版本
Mac打开终端机:〜$约瑟夫Java的版本


让我们来验证所有操作系统的输出︰

OS产量
Windows

Java“1.6.0_21”版本

Java(TM)SE运行时环境(build 1.6.0_21-b11

Java热点(TM)64位服务器VM(build 23.21-b01, mixed mode

Linux

Java“1.6.0_21”版本

Java(TM)SE运行时环境(build 1.6.0_21-b11

Java的热点(TM)64位服务器VM(build 23.21-b01, mixed mode

Mac

Java“1.6.0_21”版本

的Java(TM)SE运行时环境(build 1.6.0_21-b11

Java的热点(TM)64位服务器VM(build 23.21-b01, mixed mode

如果您没有安装Java,请安装Java软件开发工具包(SDK) http://www.oracle.com/technetwork/java/javase/downloads/index.html 。本教程使用Java 1.6.0_21作为安装版本。


第2步:设置Java环境

设置JAVA_HOME环境变量,使之指向安装在您机器上Java的基本目录位置。例如

OS产量
Windows环境变量JAVA_HOME设置为C:\Program Files\Java\jdk1.6.0_21
Linuxexport JAVA_HOME=/usr/local/java-current
Macexport JAVA_HOME=/Library/Java/Home


将 Java 编译器位置追加系统路径

OS产量
Windows追加字符串;C:\Program Files\Java\jdk1.6.0_21in 系统变量路径末尾
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应用服务器:

您可以下载最新版本的JBoss服务器http://www.jboss.org/jbossas/downloads/ 。根据下OS下载对应的档案。提取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

打开插件窗口使用工具 > 插件打开"可用插件"标签"JavaWeb  EE"类别选择"EJB ""Java EE 基地"单击安装按钮Netbeans 下载安装相应插件验证插件安装使用"安装"选项卡

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服务器

转到服务选项卡,并用鼠标右键单击服务器来添加新的服务器。

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


添加服务器

添加服务器事例向导将打开。选择JBoss和在下一步输入相关细节,在NetBeans中配置服务器。

Add Server Instance wizard will open. Select JBoss and in next step enter the relevant details to configure server in netbeans.


选择服务器

一旦一切都cofigured,你会看到以下画面。


安装的服务器


第7步:安装数据库服务器(PostgreSQL系统)。

下载最新版本的PostgreSQL数据库服务器http://www.postgresql.org/download/ 。本教程下载的是PostgreSQL 9.2

OS安装程序名称
WindowsPostgreSQL  9.2
LinuxPostgreSQL  9.2
MacPostgreSQL  9.2


EJB - 创建应用程序

若要创建一个简单的 EJB 模块我们将使用 NetBeans"新建项目"向导以下示例我们将创建一个名为Component的 ejb 模块项目

创建项目

在NetBeans IDE中,选择File > New Project >  文件>新建项目>。你会看到以下画面。


新建项目向导的步骤1


选择项目类型,Java EE 项目类别作为 Ejb 模块单击下一步 > 按钮您将看到下图所示的画面


新建项目向导的步骤2


输入项目名称和位置。单击下一步>Next > 按钮。你会看到以下画面。


新建项目向导的步骤3

选择服务器作为JBoss应用服务器 。单击Finish按钮。你会看到NetBeans中创建以下项目。


项目资源管理器


创建一个示例EJB

若要创建一个简单的 EJB我们会使用 NetBeans"新建"向导下面示例我们将创建一个在EjbComponent项目名为librarySessionBean无状态 ejb 

项目资源管理器窗口选取项目 EjbComponent右键点击选择New > Session Bean
 > 会议 Bean.你将会看到会话 Beanwizard

新建会话Bean向导

输入会话bean名称和包名称。单击Finish按钮。你会看到NetBeans中创建以下EJB类。

  • LibrarySessionBean -无状态会话bean

  • LibrarySessionBeanLocal -本地接口的会话bean


因为我们要更改到本地接口到远程接口访问基于控制台应用程序的 ejb远程/本地接口用于公开 ejb 实施业务方法


LibrarySessionBeanLocal被重命名为LibrarySessionBeanRemote和LibrarySessionBean实现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控制台输出以下内容。

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)


启动应用服务器

  • 在服务窗口服务器下选择JBoss应用服务器  Select JBoss application server under Servers in Services window

  • 右键点击它,打开上下文菜单。  Right click on it to open context menu.

  • 选择启动。  Select start.


你会看到下面的输出在NetBeans下JBoss应用服务器输出。

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控制台输出以下内容。

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应用服务器日志输出

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
 

创建客户端访问EJB

  • 在NetBeans IDE中,选择文件>新建项目>  File > New Project >

  • 在类别中选择项目类型,Java ,项目类型为Java应用程序 Java Application。单击下一步>  Next >
    按钮。

  • 输入项目名称和位置。单击Finish>按钮。我们选择的名称为EjbTester。

  • 右键点击Project Explorer窗口中的项目名称。选择属性 properties

  • 添加使用编译compile选项卡中添加项目按钮创建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.


在项目中创建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

其下创建包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)

在下面的章节中,我们将讨论完整的EJB应用程序的多个方面。


EJB - 无状态Bean

无状态会话bean是一种企业bean,它通常用来做独立操作。无状态会话Bean根据其名字没有任何关联的客户端的状态,但它可能会保留其实例的状态。 EJB容器通常会创建一些无状态Bean的对象池,并使用这些对象来处理客户端的请求。由于池,实例变量的值不能保证是相同的跨越查找/方法调用。


下面是创建一个无状态EJB所需的步骤。

  • 创建远程/本地接口公开的业务方法。  Create a remote/local interface exposing the business methods.

  • 该接口将由EJB客户端应用程序使用。  This interface will be used by the ejb client application.

  • 如果 ejb 客户端相同环境还可以使用 @Local 注释哪里部署 ejb 会话 bean。  Use @Local annotation if ejb client is in same environment where ejb session bean is to be deployed.

  • 如果 ejb 客户端不同环境还可以使用 @Remote 注释哪里部署 ejb 会话 bean。  Use @Remote annotation if ejb client is in different environment where ejb session bean is to be deployed.

  • 创建一个无状态会话bean实现上述接口。  Create a stateless session bean implementing the above interface.

  • 使用 @Stateless annotation注释表示无状态 beanEJB 容器会自动创建有关配置通过阅读批注部署过程中所需接口。  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.

远程接口

import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   //add business method declarations
}


无状态EJB

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   //implement business method 
}


示例应用程序

让我们创建一个测试EJB应用程序来测试无状态EJB。

步骤描述
1用包com.tutorialspoint.stateless下一个名字EjbComponentEJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解无状态的EJB概念。
2创建LibrarySessionBean.javaLibrarySessionBeanRemote作为EJB解释-创建应用程序一章。保持不变的文件其余部分。
3清理并生成应用程序,确保业务逻辑正在按要求。
4最后,部署JBoss应用服务器上的jar文件的形式应用。如果尚未启动JBoss应用服务器将自动被启动。
5现在创建EJB客户端,以同样的方式一个基于控制台的应用程序在EJB解释-创建应用程序一章的主题创建客户机访问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已经具备自动创建我们的会话bean JNDI入口- LibrarySessionBean /remote

  • 我们将使用查找字符串获取远程业务对象类型- com.tutorialspoint.stateless.LibrarySessionBeanRemote


JBoss应用服务器日志输出

...
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命名服务的InitialContext对象

  • InitialContext对象将被用于查找无状态会话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执行以下任务。

  •  jndi.properties 加载属性初始化输出对象

  • 在testStatelessEjb()方法中,jndi查找名称——“LibrarySessionBean /remote”来获取远程业务对象(无状态ejb)。

  • 然后用户显示库存储用户界面和他(她)被要求输入选择。

  • 如果用户输入1,系统要求书名并保存使用无状态会话bean addBook()方法的书。会话bean存储本书的实例变量。

  • 如果用户输入2,系统检索使用无状态会话bean getBooks()方法,并退出书籍。

  • 完成另一个jndi查找名称——“LibrarySessionBean /remote”来获取远程业务对象(无状态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保持多少的无状态的EJB对象。Output shown above may vary depending upon how many stateless ejb object JBoss is maintaining.

  • 如果一个无状态的EJB对象保持不变,则可能每个查找后,看到相同的书籍列表。In case a single stateless ejb object is maintained, you may see the same list of books after each lookup.

  • EJB 容器每个查找可能会返回相同无状态 ejb 对象。EJB Container may return same stateless ejb object for every lookup.

  • 无状态 ejb bean 保持实例变量直到重新启动服务器Stateless ejb bean is keeping value of instance variable till the server is not restarted.


EJB - 状态bean

有状态会话bean是一种企业bean保存会话状态与客户端。有状态会话bean按照其名称让相关客户端状态的实例变量。EJB容器创建一个单独的有状态会话bean来处理客户的每个请求。一旦请求范围结束,statelful会话bean被摧毁。


下面是创建一个有状态EJB所需的步骤。

  • 创建远程/本地接口公开的业务方法。

  • 该接口将由EJB客户端应用程序使用。

  • 如果 ejb 客户端相同环境还可以使用 @Local 注释哪里部署 ejb 会话 bean

  • 如果 ejb 客户端不同环境还可以使用 @Remote 注释哪里部署 ejb 会话 bean

  • 创建有状态会话bean执行上述接口。

  • 使用 @Stateful 注释表示状态会话 beanEJB 容器会自动创建有关配置通过阅读批注部署过程中所需接口


远程接口

import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   //add business method declarations
}


EJB状态

@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
   //implement business method 
}


示例应用程序

让我们创建一个测试EJB应用程序来测试状态EJB。

步骤描述
1创建一个包com.tutorialspoint.stateful下一个名字EjbComponent项目作为EJB解释-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解状态EJB概念。
2创建LibraryStatefulSessionBean.javaLibraryStatefulSessionBeanRemote作为EJB解释-创建应用程序一章。保持不变的文件其余部分。
3清理并生成应用程序,确保业务逻辑正在按要求。
4最后,部署JBoss应用服务器上的jar文件的形式应用。如果尚未启动JBoss应用服务器将自动被启动。
5现在创建EJB客户端,以同样的方式一个基于控制台的应用程序在EJB解释-创建应用程序一章的主题创建客户机访问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已经自动创建一个JNDI条目- LibraryStatefulSessionBean /remote

  • 我们将使用这个查询字符串获取远程业务类型的对象- com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote


JBoss应用服务器日志输出

...
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命名服务的InitialContext对象

  • InitialContext对象将被用于查找有状态会话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执行以下任务。

  •  jndi.properties 加载属性初始化输出对象

  • 在testStatefulEjb()方法中,jndi查找名称——“LibraryStatefulSessionBean /remote”来获取远程业务对象(有状态的ejb)。

  • 然后用户显示用户界面存储他/她被要求输入选择

  • 如果用户输入 1,系统要求名称保存使用有状态会话 bean addBook() 方法会话 Bean 在实例变量存储本书

  • 如果用户输入2,系统检索图书使用有状态会话bean getBooks()方法并退出。

  • 完成另一个jndi查找名称——“LibraryStatefulSessionBean /远程”来获取远程业务对象(有状态的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)
  • 上面显示输出状态,对于每个查找返回不同的状态EJB实例。

  • 有状态EJB对象是保持只单个会话值。正如在第二次运行,我们没有得到图书的任何值。


EJB - 持久性

EJB 3.0实体bean中使用EJB 2.0在很大程度上是被持久性机制所取代。现在实体bean是一个简单的POJO映射表。


以下是持久性API的关键角色

  • 实体 Entity-代表数据存储记录持久对象。这是好事,可序列化。

  • EntityManager -持久性接口进行数据操作,如添加/删除/更新/查找持久化对象(实体)上。它还有助于使用查询界面来执行查询。

  • 持久性单元 Persistence unit(persistence.xml) -持久性单元描述持久化机制的属性。

  • 数据源 Data Source(* ds.xml中) -数据源介绍像连接URL的数据存储相关的属性。用户名,密码等。


为了展示EJB的持久性机制,我们将执行以下任务。

  • 第1步:在数据库中创建表。

  • 第2步:创建对应表的实体类。

  • 第3步:创建数据源和持久性单元

  • 第4步:创建具有EntityManager实例的无状态EJB。

  • 第5步:更新无状态EJB。添加的方法来添加记录,并通过实体管理器获得数据库记录。

  • 第6步:基于控制台应用程序的客户端将访问无状态EJB在数据库中留存的数据。


创建表

默认数据库 postgres 创建

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


创建数据源和持久性单元

数据源(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>


创建无状态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();
   }
   ...
}

构建EJB模块之后,我们需要一个客户端访问bean的无状态,我们会在下一节中创建。


示例应用程序

让我们创建一个测试EJB应用程序来测试EJB的持久性机制。

步骤描述
1用包com.tutorialspoint.entity下一个名字EjbComponentEJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解EJB的持久性概念。
2包下com.tutorialspoint.entity创建Book.java,并修改它,如下图所示。
3创建LibraryPersistentBean.javaLibraryPersistentBeanRemote作为EJB解释-创建应用程序一章并修改它们,如下图所示。
4创建EjbComponent>EjbComponent>来源> conf文件夹安装文件夹和persistence.xml中 的jboss-ds.xml文件 。这些文件夹可以在Netbeans的文件选项卡中可以看出。修改这些文件,如上图所示。
6清理并生成应用程序,确保业务逻辑正在按要求。
6最后,部署JBoss应用服务器上的jar文件的形式应用。如果尚未启动JBoss应用服务器将自动被启动。
7现在创建EJB客户端,以同样的方式一个基于控制台的应用程序在EJB解释-创建应用程序一章的主题创建客户机访问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已经自动创建一个JNDI条目-LibraryPersistentBean/remote.

  • 我们将使用这个查询字符串获取远程业务类型的对象- com.tutorialspoint.stateless.LibraryPersistentBeanRemote

JBoss应用服务器日志输出

...
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命名服务的InitialContext对象

  • InitialContext对象将被用于查找无状态会话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执行以下任务。

  •  jndi.properties 加载属性初始化输出对象

  • 在testStatefulEjb()方法中,jndi查找名称——“LibraryStatefulSessionBean /remote”来获取远程业务对象(有状态的ejb)。

  • 然后用户显示库存储用户界面和他(她)被要求输入选择。

  • 如果用户输入 1,系统要求名称保存使用无状态会话 bean addBook() 方法会话 Bean 坚持通过实体管理器调用数据库

  • 如果用户输入2,系统检索图书使用有状态会话bean getBooks()方法并退出。

  • 完成另一个jndi查找名称——“LibraryStatelessSessionBean /远程”来获取远程业务对象(无状态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)
  • 上面显示的输出表明,书籍存储在持久性存储中,并从数据库中检索到。


EJB - 消息驱动Bean

消息驱动的bean是一种企业bean调用的EJB容器时,它接收一条消息队列或主题。消息驱动的bean是一个无状态bean,用于做异步任务。


为了演示使用消息驱动bean,我们将使用EJB的持久性这一章,我们要做以下工作。

  • 步骤1.创建数据库表(参见EJB的持久性这一章)。

  • 步骤2.创建实体类对应表(参见EJB的持久性这一章)。

  • 步骤3.创建数据源和持久性单元(参见EJB的持久性这一章)。

  • 步骤4.创建一个无状态EJB EntityManager实例(参见EJB的持久性这一章)。

  • 步骤5:更新无状态ejb。添加方法添加记录,记录从数据库通过实体管理器(指的EJB持久性这一章)。

  • 步骤6:创建一个名为BookQueue的队列在JBoss默认应用程序目录中。

  • 步骤7:基于控制台应用程序的客户端会发送消息到这个队列中。

  • 步骤8:创建一个消息驱动的bean将使用无状态bean保存客户数据。

  • 步骤9:的JBoss的EJB容器将调用上述消息驱动bean并将它传递客户端将被发送到邮件中。


创建队列

Create a file named jbossmq-destinations-service.xml if not exists in <JBoss Installation Folder> > server > default > deploy folder.


在这里,我们创建了一个名为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>  

当你启动JBoss,你会看到一个类似的条目在JBoss日志中

...
10:37:06,167 INFO  [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...


创建消息驱动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将其标记为消息驱动bean。

  • 其性质被定义为destinationType - 队列和目的地 - /queue/ BookQueue。

  • 它实现了MessageListener接口公开消息的方法。

  •  MessgeDrivenContext 作为资源

  • LibraryPersistentBeanRemote 无状态 bean 注射 bean为了持久性的目的

构建EjbComponent项目,并在JBoss部署它。构建和部署EJB模块后,我们需要一个客户端发送消息到JBoss队列。


示例应用程序

我们创建一个测试 EJB 应用程序测试消息驱动 Bean

步骤描述
1用包com.tutorialspoint.entity下一个名字EjbComponentEJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解EJB的持久性概念。
2包下com.tutorialspoint.entity创建Book.java作为EJB的持久性创建章
3创建LibraryPersistentBean.javaLibraryPersistentBeanRemote作为EJB的持久性创建章
4创建EjbComponent>EjbComponent>来源> conf文件夹安装文件夹和persistence.xml中 的jboss-ds.xml文件 。这些文件夹可在文件选项卡中可以看出在Netbeans的作为EJB的持久性创建章
5com.tutorialspoint.messagebean下创建LibraryMessageBean.java,并修改它,如下图所示。
6在JBoss中创建BookQueue队列如上所述。
7清理并生成应用程序,确保业务逻辑正在按要求。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号