JavaEE(11) - 消息驱动EJB
1. MDB作为异步消费者的本质
2. MDB的运行机制
3. 使用@MessageDriven修饰MDB(需要messageListenerInterface)
4. 实现MessageListener
5. MDB的生命周期
6. 在MDB中使用依赖注入
7. MDB中的事务管理和异常管理
------------------------------------------------
1. MDB作为异步消费者的本质
MDB存在于EJB容器之中,可以利用EJB提供的事务、安全和并发性等系统服务。MDB并不直接与客户端交互,只是一个JMS消息的异步消费者。
EAO: Entiry Access Object
2. MDB的运行机制
MDB是由无状态Session Bean变化而来的,因此在用法上与其相似,不会保存客户端的调用状态,可被多个客户端共享。客户端需要以同步方式来调用无状态Session Bean,MDB不允许直接调用,它只是一个消息监听者。
消息生产者(发送消息)-->JMS消息目的(触发onMessage()方法)-->MDB(调用业务方法)-->Session Bean
3. 使用@MessageDriven修饰MDB
#1. EJB开发(Net Beans创建EJB Module, 项目名称:SimpleMDB)
SimpleMDB.java
package org.crazyit.jms; import javax.ejb.*;
import javax.jms.*; @MessageDriven(activationConfig
= {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "MessageQueue")
} ,
messageListenerInterface = javax.jms.MessageListener.class,
mappedName = "MessageQueue"
)
public class SimpleMDB { public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
String content = txt.getText();
System.out.println("JMS信息中信息为:" + content);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
#2. 消息发送(Net Beans创建Java Project, 项目名称:SendMsg)
SendMsg.java
package lee; import javax.jms.*;
import javax.naming.*;
import java.util.Properties; public class SendMsg { public void sendMessage() throws NamingException, JMSException {
//定义WebLogic默认连接工厂的JNDI
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
//获取JNDI服务所需的Context
Context ctx = getInitialContext();
//通过JNDI查找获取连接工厂
ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup(CONNECTION_FACTORY_JNDI);
//通过JNDI查找获取消息目的
Destination dest = (Destination) ctx.lookup("MessageQueue");
//连接工厂创建连接
Connection conn = connFactory.createConnection();
//JMS连接创建JMS会话
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
//JMS会话创建消息生产者
MessageProducer sender = session.createProducer(dest);
//设置消息生产者生产出来的消息的传递模式、有效时间。
sender.setDeliveryMode(DeliveryMode.PERSISTENT);
sender.setTimeToLive(20000);
//通过JMS会话创建一个文本消息
TextMessage msg = session.createTextMessage();
//msg.setStringProperty("ConType","txt");
//设置消息内容
msg.setText("Hello");
//发送消息
sender.send(msg);
msg.setText("Welcome to JMS");
//再次发送消息
sender.send(msg);
//关闭资源
session.close();
conn.close();
} //工具方法,用来获取命名服务的Context对象
private Context getInitialContext() {
// 参见(4)
} public static void main(String[] args) throws Exception {
SendMsg sender = new SendMsg();
sender.sendMessage();
}
}
SendMapMsg.java
package lee; import javax.jms.*;
import javax.naming.*;
import java.util.Properties; public class SendMapMsg { public void sendMessage() throws NamingException, JMSException {
//定义WebLogic默认连接工厂的JNDI
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
//获取JNDI服务所需的Context
Context ctx = getInitialContext();
//通过JNDI查找获取连接工厂
ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup(CONNECTION_FACTORY_JNDI);
//通过JNDI查找获取消息目的
Destination dest = (Destination) ctx.lookup("MessageQueue");
//连接工厂创建连接
Connection conn = connFactory.createConnection();
//JMS连接创建JMS会话
Session session = conn.createSession(false/*不是事务性会话*/, Session.AUTO_ACKNOWLEDGE);
//JMS会话创建消息生产者
MessageProducer sender = session.createProducer(dest);
//设置消息生产者生产出来的消息的传递模式、有效时间。
sender.setDeliveryMode(DeliveryMode.PERSISTENT);
sender.setTimeToLive(20000);
//通过JMS会话创建一个文本消息
MapMessage msg = session.createMapMessage();
//设置消息内容
msg.setString("name", "孙悟空");
msg.setString("gender", "男");
msg.setInt("age", 500);
//发送消息
sender.send(msg);
//关闭资源
session.close();
conn.close();
} //工具方法,用来获取命名服务的Context对象
private Context getInitialContext() {
// 参见(4)
} public static void main(String[] args) throws Exception {
SendMapMsg sender = new SendMapMsg();
sender.sendMessage();
}
}
4. 实现MessageListener
#1. EJB开发(Net Beans创建EJB Module, 项目名称:SimpleMDBListener)
SimpleMDB.java
package org.crazyit.jms; import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; @MessageDriven(activationConfig ={
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "MessageQueue")
},
mappedName = "MessageQueue"
)
public class SimpleMDB implements MessageListener { @Override
public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
String content = txt.getText();
System.out.println("JMS信息中信息为:" + content);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
5. MDB的生命周期
#1. EJB开发(Net Beans创建EJB Module, 项目名称:Lifecycle)
LifecycleMDB.java
package org.crazyit.jms; import javax.ejb.*;
import javax.jms.*;
import javax.annotation.*; @MessageDriven(activationConfig
= {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "MessageQueue")
},
mappedName = "MessageQueue"
)
public class LifecycleMDB implements MessageListener { public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
String content = txt.getText();
System.out.println("JMS信息中信息为:" + content);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
} @PostConstruct
public void myInit() {
System.out.println("--初始化方法--");
} @PreDestroy
public void myDestroy() {
System.out.println("--销毁之前的方法--");
}
}
6. 在MDB中使用依赖注入
#1. EJB开发(Net Beans创建EJB Module, 项目名称:Injection)
Injection.java
package org.crazyit.jms; import javax.ejb.*;
import javax.jms.*; import org.crazyit.service.*; @MessageDriven(activationConfig
= {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "MessageQueue")
},
mappedName = "MessageQueue"
)
public class Injection implements MessageListener { @EJB(name = "StudentBean")
private Student student; public void onMessage(Message msg) {
try {
if (msg instanceof MapMessage) {
MapMessage map = (MapMessage) msg;
String name = map.getString("name");
String gender = map.getString("gender");
int age = map.getInt("age");
//调用Session Bean的方法添加学生。
student.add(name, gender, age);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
Student.java
package org.crazyit.service; import javax.ejb.*; @Remote
public interface Student {
void add(String name, String gender, int age) throws Exception;
}
StudentBean.java
package org.crazyit.service; import java.sql.*;
import javax.sql.*;
import javax.ejb.*;
import javax.annotation.*; @Stateless(name = "StudentBean")
public class StudentBean implements Student { //采用依赖注入获取数据源
@Resource(name = "javaee")
private DataSource ds; public void add(String name, String gender, int age) throws Exception {
Connection conn = null;
PreparedStatement pstmt = null;
try {
//通过数据源获取数据库连接
conn = ds.getConnection();
//使用PreparedStatement执行SQL语句
pstmt = conn.prepareStatement("insert into student values(null , ? , ? , ?)");
pstmt.setString(1, name);
pstmt.setString(2, gender);
pstmt.setInt(3, age);
pstmt.executeUpdate();
}
finally {
pstmt.close();
conn.close();
}
}
}
7. MDB中的事务管理和异常管理
MDB同样支持CMT和BMT,使用CMT,采用如下两种Annotation来修饰MDB的Bean实现类或方法:
@TransactionManagement:配置事务管理类型
@TransactionAttribute:配置事务管理属性
如果希望CMT事务管理机制遇到自定义异常时也能回滚事务,有两种处理方式:
#1. 定义该自定义异常类时使用@ApplicationException(rollback=true)
#2. 程序中显式捕获该异常,然后调用ctx.setRollback(true);代码来控制事务回滚。
JavaEE(11) - 消息驱动EJB的更多相关文章
- EJB3.0 EJB开发消息驱动bean
(7)EJB3.0 EJB开发消息驱动bean JMS 一: Java消息服务(Java Message Service) 二:jms中的消息 消息传递系统的中心就是消息.一条 Message 由三个 ...
- JMS和消息驱动Bean(MDB)
一.说明 本示例使用的ActiveMQ作为消息中间件,服务器为Glassfish,使用JMS发送消息,在MDB接收到消息之后做打印输出. 二.ActiveMQ安装配置 1.安装console war包 ...
- 消息驱动bean(MDB)实例
到眼下为止前面介绍的有关JavaEE的东西都是同步的.也就是说调用者调用某个方法.那么这种方法必须马上运行并返回运行结果. 用官方一些的语言来说就是"client通过业务接口调用一个方法,在 ...
- 消息驱动Bean
消息驱动bean是专门用来处理基于消息请求的组件.MDB负责处理消息,而EJB容器则负责处理服务(事务,安全,并发,消息确认等),使Bean的开发者集中精力在处理消息的业务逻辑上. 消息驱动Bean. ...
- Intellij IDEA 创建消息驱动Bean - 接收JMS消息
除了同步方式的调用之外,有时还需要异步调用,用来处理不需要即时处理的信息,例如短信.邮件等,这需要使用EJB中的独特组件——消息驱动Bean(Message-Driven Bean,MDB),它提供了 ...
- EJB_消息驱动发展bean
消息驱动发展bean Java信息服务(Java MessageService) Java 信息服务(Java Message Service,简称 JMS)是用于訪问企业消息系统的开发商中立的API ...
- EJB_开发消息驱动bean
开发消息驱动bean Java消息服务(Java MessageService) Java 消息服务(Java Message Service,简称 JMS)是用于访问企业消息系统的开发商中立的API ...
- SpringCloud实战9-Stream消息驱动
官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架. 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互 ...
- 基于Kafka消息驱动最终一致事务(二)
实现用例分析 上篇基于Kafka消息驱动最终一致事务(一)介绍BASE的理论,接着我们引入一个实例看如何实现BASE,我们会用图7显示的算法实现BASE.
随机推荐
- 基于Office 365 无代码工作流分析-需求基本分析!
客户需求分析: 嘉昊信息是一家IT创业型公司,因为公司初创,有较多的招聘员工的需求,公司近期购买了Office 365,因为招聘工作繁琐,HR人员须要做非常多反复繁琐工作,HR主管提议开发一个招 ...
- InputStreamReader 和 OutputStreamWriter类使用方法简单介绍,及演示。
InputStreamReader 和 OutputStreamWriter类使用方法简单介绍. 一.InputStreamReader类 InputStreamReader 将字节流转换为字符流.是 ...
- Ubuntu 如何重新安裝 Unity ?
阿舍在刪除 Qt 的時候下錯指令,結果,就把 Unity 給移除掉了,雖然,阿舍從此就知道 Unity 和 Qt 有不分離的關係,不過,就沒有Unity可以用了,這樣阿舍要試東西就不是很方便了哩 ! ...
- HDU ACM 4578 Transformation->段树-间隔的变化
分析:复杂的经营分部树. 只有一个查询操作,这是要求[l,r]的数量之间p钍总和.并不是所有的查询所有节点,会议TLE.最好的是查询部件[a.b].所有这个区间值我们是平等的,即能返回(b-a+1)* ...
- windows中间vmware的Linux系统安装jdk步骤
1.设置文件的享受,对于本地阅读windows档 于vmware虚拟机设置共享文件夹,那么共享文件中,你可以 2.然后打开虚拟机上,使用root输入账户,然后,在夹/mnt/hgfs/ 共享文件了 ...
- Hadoop-2.2.0中文文档—— MapReduce下一代- 可插入的 Shuffle 和 Sort
简单介绍 可插入的 shuffle 和 sort 功能,同意在shuffle 和 sort 逻辑中用可选择的实现类替换.这个情况的样例是:用一个不是HTTP的应用协议,如RDMA来 shuffle 从 ...
- Dictionary带来的一种隐式内存泄漏
当心Dictionary带来的一种隐式内存泄漏 最近在看Dictionary的源代码的时候, 突然想到Dictionary的不当使用中有一种隐含内存泄漏的可能. 简化使用场景 小A正在写一个简单的图书 ...
- 认识Require
1. 加载require.js文件 <script type="text/javascript" src="js/require.js" data-mai ...
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
简单的Demo,用于了解WebAPI如何同时接收文件及数据,同时提供HttpClient模拟如何同时上传文件和数据的Demo,下面是HttpClient上传的Demo界面 1.HttpClient部分 ...
- 轻松搭建Windows8云平台开发环境
原文:轻松搭建Windows8云平台开发环境 Windows Store应用是基于Windows 8操作系统的新一代Windows应用程序,其开发平台以及运行模式和以往传统平台略有不同.为了帮助更多开 ...