EJB快速指南
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已经安装在你的机器上。
系统需求
JDK | 1.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 |
Linux | export JAVA_HOME=/usr/local/java-current |
Mac | export JAVA_HOME=/Library/Java/Home |
将 Java 编译器位置追加到系统路径
OS | 产量 |
---|---|
Windows | 追加的字符串;C:\Program Files\Java\jdk1.6.0_21in 到系统变量,路径的末尾 |
Linux | export 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 | 安装程序名称 |
---|---|
Windows | Netbeans 7.3 |
Linux | Netbeans 7.3 |
Mac | Netbeans 7.3 |
第4步:安装JBoss应用服务器:
您可以下载最新版本的JBoss服务器http://www.jboss.org/jbossas/downloads/ 。根据下OS下载对应的档案。提取Jboss到你机器上的任意位置。
OS | 文件名 |
---|---|
Windows | jboss-5.1.0.GA-jdk6.zip |
Linux | 的jboss-5.1.0.GA-src.tar.gz |
Mac | 的jboss-5.1.0.GA-src.tar.gz |
步骤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 | 安装程序名称 |
---|---|
Windows | PostgreSQL 9.2 |
Linux | PostgreSQL 9.2 |
Mac | PostgreSQL 9.2 |
EJB - 创建应用程序
若要创建一个简单的 EJB 模块,我们将使用 NetBeans"新建项目"向导。在以下示例中,我们将创建一个名为Component的 ejb 模块项目。
创建项目
在NetBeans IDE中,选择File > New Project > 文件>新建项目>。你会看到以下画面。
选择项目类型下,Java EE 项目类别作为 Ejb 模块。单击下一步 > 按钮。您将看到下图所示的画面。
输入项目名称和位置。单击下一步>Next > 按钮。你会看到以下画面。
选择服务器作为JBoss应用服务器 。单击Finish按钮。你会看到NetBeans中创建以下项目。
创建一个示例EJB
新 > 会议 Bean.你将会看到新的会话 Beanwizard。
输入会话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注释来表示它的无状态 bean。EJB 容器会自动创建有关的配置或通过阅读此批注在部署过程中的所需的接口。 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下一个名字EjbComponent在EJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解无状态的EJB概念。 |
2 | 创建LibrarySessionBean.java和LibrarySessionBeanRemote作为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 注释来表示它有状态会话 bean。EJB 容器会自动创建有关的配置或通过阅读此批注在部署过程中的所需的接口。
远程接口
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.java和LibraryStatefulSessionBeanRemote作为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下一个名字EjbComponent在EJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解EJB的持久性概念。 |
2 | 包下com.tutorialspoint.entity创建Book.java,并修改它,如下图所示。 |
3 | 创建LibraryPersistentBean.java和LibraryPersistentBeanRemote作为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下一个名字EjbComponent在EJB作为解释的创建项目-创建应用程序一章。您也可以使用EJB创建的项目-创建应用程序章这样本章了解EJB的持久性概念。 |
2 | 包下com.tutorialspoint.entity创建Book.java作为EJB的持久性创建章 |
3 | 创建LibraryPersistentBean.java和LibraryPersistentBeanRemote作为EJB的持久性创建章 |
4 | 创建EjbComponent>在EjbComponent>来源> conf文件夹安装文件夹和persistence.xml中 的jboss-ds.xml文件 。这些文件夹可在文件选项卡中可以看出在Netbeans的作为EJB的持久性创建章 |
5 | 包com.tutorialspoint.messagebean下创建LibraryMessageBean.java,并修改它,如下图所示。 |
6 | 在JBoss中创建BookQueue队列如上所述。 |
7 | 清理并生成应用程序,确保业务逻辑正在按要求。 |