自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Eclipse+JBoss+EJB3消息驅(qū)動Bean

開發(fā) 后端
本文講述Eclipse+JBoss+EJB3消息驅(qū)動Bean。在前面的文章中給出的SessionBean的例子都是同步調(diào)用SessionBean方法的。在某些情況下,由于SessionBean方法的執(zhí)行時間比較長,這就需要異步地調(diào)用該方法。

在前面的文章中給出的SessionBean的例子都是同步調(diào)用SessionBean方法的,也就是說,只有當方法中的代碼都執(zhí)行完,才能返回到客戶端。但在某些情況下,由于SessionBean方法的執(zhí)行時間比較長,這就需要異步地調(diào)用該方法,否則客戶端就需要等待比較長的時間。要實現(xiàn)異步調(diào)用,就需要使用本要講的消息驅(qū)動Bean。消息驅(qū)動Bean的基本原理是客戶端向消息服務(wù)器發(fā)送一條消息后,消息服務(wù)器會將該消息保存在消息隊列中。在這時消息服務(wù)器中的某個消費者(讀取并處理消息的對象)會讀取該消息,并進行處理。發(fā)送消息的客戶端被稱為消息生產(chǎn)者。

本文給出的消息驅(qū)動Bean的例子的基本功能是客戶端向消息服務(wù)器發(fā)送一條消息(該消息實際上是一個實體Bean的對象實例),然后消息消費者讀取這條消息后,將消息中的實體Bean持久化。實現(xiàn)消息驅(qū)動Bean的步驟如下:

一、實現(xiàn)實體Bean

  1. package entity;  
  2.  
  3. import java.io.Serializable;  
  4. import java.util.Date;  
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.GenerationType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.Table;  
  11.  
  12. @Entity 
  13. @Table(name="t_date")  
  14. public class DateBean implements Serializable  
  15. {  
  16.     private int id;  
  17.     private Date myDate;  
  18.     @Id 
  19.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
  20.     public int getId()  
  21.     {  
  22.         return id;  
  23.     }  
  24.       
  25.     public void setId(int id)  
  26.     {  
  27.         this.id = id;  
  28.     }  
  29.     @Column(name="mydate")  
  30.     public Date getMyDate()  
  31.     {  
  32.         return myDate;  
  33.     }  
  34.     public void setMyDate(Date myDate)  
  35.     {  
  36.         this.myDate = myDate;  
  37.     }  
  38.       
  39. }  

二、編寫消息驅(qū)動Bean

消息驅(qū)動Bean必須實現(xiàn)MessageListener接口,當該消息驅(qū)動Bean接收到一個消息后,EJB容器就會調(diào)用MessageListener接口的onMessage方法來理該消息。消息驅(qū)動Bean的代碼如下:

  1. package service;  
  2.  
  3. import javax.ejb.ActivationConfigProperty;  
  4. import javax.ejb.EJBException;  
  5. import javax.ejb.MessageDriven;  
  6. import javax.jms.Message;  
  7. import javax.jms.MessageListener;  
  8. import javax.jms.ObjectMessage;  
  9. import javax.persistence.EntityManager;  
  10. import javax.persistence.PersistenceContext;  
  11. import entity.DateBean;  
  12.  
  13. @MessageDriven( activationConfig =  {          
  14.         @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),  
  15.         @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MDBQueue")  
  16.       })  
  17. public class DateMessageBean implements MessageListener  
  18. {  
  19.     @PersistenceContext(unitName = "myentity1")  
  20.     private EntityManager em;  
  21.  
  22.     @Override 
  23.     public void onMessage(Message message)  
  24.     {  
  25.         try 
  26.         {  
  27.             if(message instanceof ObjectMessage)  
  28.             {  
  29.  
  30.                 ObjectMessage objmsg = (ObjectMessage) message;  
  31.                 DateBean dateBean = (DateBean) objmsg.getObject();  
  32.                 em.persist(dateBean);  
  33.                 System.out.println("成功持久化DateBean對象!");  
  34.             }  
  35.             else 
  36.             {  
  37.                 System.out.println("消息類型錯誤!");  
  38.             }  
  39.         }  
  40.         catch (Exception e)  
  41.         {  
  42.             throw new EJBException(e);  
  43.         }  
  44.  
  45.     }  
  46.  
  47. }  

消息驅(qū)動Bean需要使用@MessageDriven進行注釋。要注意的是destination屬性的值是queue/MDBQueue。JBoss不會自已建立一個Queue對象,因此,需要手工來配置Queue對象。讀者可以\server\default\deploy目錄中建立一個xxx-service.xml文件,其中xxx可以任意取值,但必須跟“-service”后綴,例如,abc-service.xml。該文件可以放在deploy或其子目錄(可以是多層子目錄)中。該文件的內(nèi)容如下:

  1. < xml version="1.0" encoding="UTF-8"?> 
  2. < server> 
  3.   < mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=MDBQueue"> 
  4.     < depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManagerdepends> 
  5.   < mbean> 
  6. < server> 
  7.      

要注意的是,元素的name屬性值中的name必須是MDBQueue,要與queue/MDBQueue中的/后面的部分一致。如果不進行上面的配置,在啟動JBOSS時就會拋出如下的異常:

javax.naming.NameNotFoundException: MDBQueue not bound

也可以將元素放在deploy目錄中的其他以-service.xml結(jié)尾的文件中。

如果不設(shè)置destination屬性的值,在啟動JBoss是會拋出如下的異常:

  1. org.jboss.deployers.spi.DeploymentException: Required config property RequiredConfigPropertyMetaData@174098f[name=destination descriptions=[DescriptionMetaData@4ca30b[language=zh]]] for messagingType 'javax.jms.MessageListener' not found in activation config [ActivationConfigProperty(destinationType=javax.jms.Queue), ActivationConfigProperty(connectionFactoryJndiName=MyQueueConnectionFactory), ActivationConfigProperty(destinationName=MyRequestQueue)] ra=jboss.jca:service=RARDeployment,name='jms-ra.rar' 
  2. ... ... 

三、編寫調(diào)用消息驅(qū)動Bean的SessionBean

  1. package service;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.Date;  
  5. import java.util.List;  
  6. import javax.annotation.Resource;  
  7. import javax.ejb.Stateless;  
  8. import javax.jms.Connection;  
  9. import javax.jms.ConnectionFactory;  
  10. import javax.jms.MessageProducer;  
  11. import javax.jms.ObjectMessage;  
  12. import javax.jms.Queue;  
  13. import javax.jms.Session;  
  14. import javax.persistence.EntityManager;  
  15. import entity.DateBean;  
  16. import entity.Greeting;  
  17.  
  18. @Stateless 
  19. public class GreeterBean implements Greeter  
  20. {  
  21.     @Resource(mappedName = "ConnectionFactory")  
  22.     private ConnectionFactory cf;  
  23.     @Resource(mappedName = "queue/MDBQueue")  
  24.     private Queue queue;  
  25.  
  26.     @Override 
  27.     public String greet(String message)  
  28.     {  
  29.         try 
  30.         {  
  31.             DateBean db = new DateBean();  
  32.             db.setMyDate(new Date());  
  33.             Connection connection = cf.createConnection();  
  34.             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  
  35.             MessageProducer messageProducer = session.createProducer(queue);  
  36.             ObjectMessage objectMessage = session.createObjectMessage();  
  37.             objectMessage.setObject(db);  
  38.             messageProducer.send(objectMessage);  
  39.             connection.close();  
  40.             System.out.println("成功發(fā)送消息!");  
  41.         }  
  42.         catch (Exception e)  
  43.         {  
  44.             System.out.println("發(fā)送消息失??!");  
  45.         }  
  46.  
  47.         return "方法成功返回";  
  48.  
  49.     }  
  50. }  

在上面的代碼中使用ObjectMessage對象來包裝要向消息服務(wù)器發(fā)送的實體Bean的對象實例。

除了可以在SessionBean中訪問消息驅(qū)動Bean外,還可以在不同的機器上通過jndi來查找并調(diào)用消息驅(qū)動Bean,代碼如下:

  1. package test;  
  2.  
  3. import java.util.Date;  
  4. import javax.ejb.EJB;  
  5. import javax.jms.Destination;  
  6. import javax.jms.MessageProducer;  
  7. import javax.jms.ObjectMessage;  
  8. import javax.jms.Queue;  
  9. import javax.jms.QueueConnection;  
  10. import javax.jms.QueueConnectionFactory;  
  11. import javax.jms.QueueSession;  
  12. import javax.jms.TextMessage;  
  13. import javax.naming.InitialContext;  
  14. import entity.DateBean;  
  15.  
  16. import service.Greeter;  
  17.  
  18. public class Client  
  19. {  
  20.  
  21.     public static void main(String[] args) throws Exception  
  22.     {  
  23.         InitialContext ctx = new InitialContext();  
  24.         QueueConnection connection = null;  
  25.         QueueSession session = null;  
  26.         QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");  
  27.         connection = factory.createQueueConnection();  
  28.         session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);  
  29.         Destination destination = (Queue) ctx.lookup("queue/MDBQueue");  
  30.         MessageProducer messageProducer = session.createProducer(destination);  
  31.         ObjectMessage objectMessage = session.createObjectMessage();  
  32.         DateBean db = new DateBean();  
  33.         db.setMyDate(new Date());  
  34.         objectMessage.setObject(db);  
  35.         messageProducer.send(objectMessage);  
  36.         connection.close();  
  37.         System.out.println("成功發(fā)送消息!");  
  38.     }  
  39. }  

【編輯推薦】

  1. Eclipse+JBoss+EJB3通過繼承實體Bean將單個表映射成多個表
  2. Eclipse+JBoss+EJB3實現(xiàn)Entity Bean的多對多映射
  3. Eclipse+JBoss+EJB3在Servlet中訪問EntityManager對象
  4. Eclipse+JBoss+EJB3使用命名查詢執(zhí)行JPQL
  5. Eclipse+JBoss+EJB3實體Bean的連接策略
責任編輯:book05 來源: BlogJava
相關(guān)推薦

2009-06-24 15:56:47

實體Bean連接策略

2009-06-10 11:42:26

Session BeaEclipse+JBo

2009-06-10 11:09:40

配置文件SessionEclipse+JBo

2009-06-10 12:34:01

Session BeaEclipse+JBo

2009-06-24 15:53:08

Entity Bean多對多映射

2009-06-10 11:36:45

有狀態(tài)的SessionEclipse+JBo

2009-06-24 15:47:13

實體Bean

2009-06-24 15:51:47

Entity Bean一對多映射

2009-06-24 15:57:44

JPQL命名查詢

2009-06-24 15:49:54

Entity Bean一對一映射

2009-06-24 15:58:15

EntityManag

2009-06-24 15:55:09

EclipseJBossJ2ee

2009-06-24 16:00:00

2009-06-10 12:54:35

無狀態(tài)的SessionEclipse+JBo

2009-06-15 16:06:25

JBoss IDE

2009-09-24 12:05:35

2009-06-17 08:51:26

Eclipse啟動JB

2009-06-17 09:01:20

JBoss訪問EJB

2009-06-16 15:15:18

WebLogic EJ

2009-06-29 17:07:54

EJB部署Jboss
點贊
收藏

51CTO技術(shù)棧公眾號