??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩精品一区二区三区swag,在线国产中文字幕,久久男人的天堂http://www.aygfsteel.com/keweibo/category/28981.htmlAs long as you are there to lead me ,I won't lose my way zh-cnTue, 15 Jan 2008 15:37:08 GMTTue, 15 Jan 2008 15:37:08 GMT60?用Spring快速开发jms应用QJBOSS服务器)(j)http://www.aygfsteel.com/keweibo/articles/175545.htmlKEKETue, 15 Jan 2008 13:00:00 GMThttp://www.aygfsteel.com/keweibo/articles/175545.htmlhttp://www.aygfsteel.com/keweibo/comments/175545.htmlhttp://www.aygfsteel.com/keweibo/articles/175545.html#Feedback1http://www.aygfsteel.com/keweibo/comments/commentRss/175545.htmlhttp://www.aygfsteel.com/keweibo/services/trackbacks/175545.htmlJava消息服务(JMS)是用于编写用异步消息传递的JEE应用E序的API。传l的使用JMS APIq行消息传递的实现包括多个步骤Q例如JNDI查询队列q接工厂和Queue资源Q在实际发送和接收消息前创Z个JMS?x)话?

   Spring框架则简化了(jin)使用JEElg(包括JMS)的Q务。它提供的模板机刉藏了(jin)典型的JMS实现的细节,q样开发h员可以集中精力放在处理消息的实际工作中,而不用担?j)如何去创徏Q访问或清除JMS资源?/p>

   本文对Spring JMS API作一个概qͼq过一个运行在JBoss MQ服务器上的web例程来介l如何用Spring JMS API来异步处理(发送和接收Q消息。我通过传统JMS实现和Spring JMS实现两者间的比较,来展CZ用Spring JMS处理消息是如何的单和灉|?/p>

异步消息传递和面向服务架构

  在现实中Q大多数webh都是同步处理的。例如,当用戯d一个网站,首先输入用户名和密码Q然后服务器验证d合法性。如果验证成功,E序允许该用户q入|站。这里,dh在从客户端接收以后被x处理?jin)。信用卡验证是另一个同步处理的例子Q只有服务器证实输入的信用卡h有效的,同时客户在帐户上有够的存款Q客h被允许l操作。但是让我们思考一下在序处理pȝ上的支付l算步骤。一旦系l证实该用户信用卡的信息是准的Qƈ且在帐户上有_的资金,׃必等到所有的支付l节落实、{账完成。支付结可以异步方式进行,q样客户可以l箋q行核查操作?/p>

   需要比典型同步h耗费更长旉的请求,可以使用异步处理。另一个异步处理的例子是,在本地贷Ƒ֤理程序中Q提交至自动扉KpȝQAUSQ的信用h处理q程。当借方提交h甌后,抉|公司?x)向AUS发送请求,以获取信用历史记录。由于这个请求要求得到全面而又详细的信用报告,包括借方C和过ȝ帐户Q最q的付款和其他胦(ch)务资料,服务器需要耗费较长的时_(d)几小时或着有时甚至是几天)(j)来对q些h作出响应。客L(fng)E序Q应用)(j)要与服务器连接ƈ耗费如此长的旉来等待结果,q是毫无意义的。因此通信应该是异步发生的Q也是Q一旦请求被提交Q它?yu)p攄在队列中Q同时客L(fng)与服务器断开q接。然后AUS服务从指定的队列中选出hq行处理Qƈ处理得到的消息攄在另一个消息队列里。最后,客户端程序从q个队列中选出处理l果Q紧接着处理q个信用历史数据?/p>

JMS

   如果(zhn)用过JMS代码Q?zhn)会(x)发现它与JDBC或JCA很像。它所包含的样本代码创建或JMS资源对象回溯Q得每一ơ?zhn)需要写一个新cL发送和接收消息Ӟ都具有更好的代码密集性和重复性。以下序列显CZ(jin)传统JMS实现所包括的步骤:(x)

  1. 创徏JNDI初始上下文(contextQ?
  2. 从JNDI上下文获取一个队列连接工厂?
  3. 从队列连接工厂中获取一个Quene?
  4. 创徏一个Session对象?
  5. 创徏一个发送者(senderQ或接收者(receiverQ对象?
  6. 使用步骤5创徏的发送者或接收者对象发送或接收消息?
  7. 处理完消息后Q关闭所有JMS资源?

(zhn)可以看刎ͼ步骤6是处理消息的唯一地方。其他步骤都只是理与实际业务要求无关的JMS资源Q但是开发h员必ȝ写ƈl护q些额外步骤的代码?/p>

Spring JMS

   Spring框架提供?jin)一个模板机制来隐藏Java APIs的细节。JEE开发h员可以用JDBCTemplate和JNDITemplatecL分别讉K后台数据库和JEE资源Q数据源Q连接池Q。JMS也不例外。Spring提供JMSTemplatec,因此开发h员不用ؓ(f)一个JMS实现ȝ写样本代码。接下来是在开发JMS应用E序时Spring所h一些的优势?/p>

  1. 提供JMS抽象APIQ简化了(jin)讉K目标Q队列或主题Q和向指定目标发布消息时JMS的用?
  2. JEE开发h员不需要关?j)JMS不同版本Q例如JMS 1.0.2与JMS 1.1Q之间的差异?
  3. 开发h员不必专门处理JMS异常Q因为Spring为所有JMS异常提供?jin)一个未l检查的异常Qƈ在JMS代码中重新抛出?

CZE序

        说明Q因为只是ؓ(f)?jin)演C如何用spring~写jms的应用,所以本例没有什么实际用途?/p>

        E序功能QMessageProducer.javaҎ(gu)一用户信息产生一个消息发送到 JMS ProviderQ由MessageConsumer.java接收?/p>

1.在Jboss里配|XML文g创徏一个新的JMS provider?br /> 打开位于%JBOSS_HOME%server\default\deploy\jms文g夹下的jbossmq-destinations-service.xml文gQ加入以下代码片断:(x)
 <!--  Register User Send/Receive Queue  -->
 <mbean code="org.jboss.mq.server.jmx.Queue"
   name="jboss.mq.destination:service=Queue,name=registerUserQueue">
   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
 </mbean>
 <!--  Register User Send/Receive Topic  -->
 <mbean code="org.jboss.mq.server.jmx.Topic"
  name="jboss.mq.destination:service=Topic,name=registerUserTopic">
   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
 </mbean>
2.在spring的配|文件中配置JMSlg的具体细节?br />  Q?QJNDI上下文是取得JMS资源的v始位|,因此首先我们要配|JNDI模板Q?br />     <!-- JNDI上下?它是取得JMS资源的v始位|? -->
   <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
     <props>
      <prop key="java.naming.factory.initial">
       org.jnp.interfaces.NamingContextFactory
      </prop>
      <prop key="java.naming.provider.url">localhost</prop>
      <prop key="java.naming.factory.url.pkgs">
       org.jnp.interfaces:org.jboss.naming
      </prop>
     </props>
    </property>
   </bean>
   注意Q此JNDI模板用到?jin)org.jnp.interfaces.NamingContextFactory所以要?JBOSS_HOME%\client下的jbossall-client.jar加到你的目的classpath中?br /> Q?Q配|连接工厂:(x)
   <!-- JMSq接工厂 -->
     <bean id="jmsConnectionFactory"class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
     <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
     <value>XAConnectionFactory</value>
    </property>
   </bean>
   注意QXAConnectionFactoryq个JNDI名字是在%JBOSS_HOME%server\default\deploy\jms文g夹下的jms-ds.xml中定义的(它是由JBoss指定??br />  Q?Q配|JmsTemplatelg。在例程中我们用JmsTemplate102。同时用defaultDestination属性来指定JMS目标?br />   <!-- JMS模板配置 -->
  <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102">
   <property name="connectionFactory" ref="jmsConnectionFactory" />
   <property name="defaultDestination" ref="destination" />
   <property name="pubSubDomain">
    <value>true</value>
   </property>
   <!-- {待消息的时?ms) -->
   <property name="receiveTimeout">
         <value>30000</value>
      </property>
  </bean>
  注意Q如果用topic-subscribe(主题订阅)模式Q该模板的pubSubDomain属性gؓ(f)true;若用PToP(点对?模式QpubSubDomain属性gؓ(f)false或不配置该属性?br />  (4)定义一个JMS目标来发送和接收消息:
  <bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
   </property>
   <property name="jndiName">
    <value>topic/registerUserTopic</value>
   </property>
  </bean>
 (5)配置发送者和接收者组?
  <!-- 消息发布?-->
  <bean id="msgProducer" class="com.boco.jms.MessageProducer">
   <property name="jmsTemplate" ref="jmsTemplate" />
  </bean>
  <!-- 消息接收?-->
  <bean id="msgConsumer" class="com.boco.jms.MessageConsumer">
   <property name="jmsTemplate" ref="jmsTemplate" />
  </bean>
3.相应的类:
 (1). User对象?br />    /**
   *  User.java
   *  created on Jul 2, 2006
   *  Copyrights 2006 BOCO,Inc. All rights reserved.
   */
  package com.boco.dto;
  
  import java.io.Serializable;
  
  /**
   * desc: 用户信息 Bean
   * @author qiujy
   */
  public class User {
   private int id;
   private String username;
   private String password;
   private String email;
   
   public User(){}
   
   //以下为Getter,setterҎ(gu)?br />    ......
  }
  
 (2).消息生者:(x)
   /**
   *  MessageProducer.java
   *  created on Jul 22, 2006
   *  Copyrights 2006 BOCO,Inc. All rights reserved.
   */
  package com.boco.jms;
  
  import javax.jms.JMSException;
  import javax.jms.MapMessage;
  import javax.jms.Message;
  import javax.jms.Session;
  
  import org.springframework.jms.core.JmsTemplate;
  import org.springframework.jms.core.MessageCreator;
  
  import com.boco.dto.User;
  
  /**
   * desc:消息生?br />    * @author qiujy
   *
   */
  public class MessageProducer {
   /** JMS模板 */
   private JmsTemplate jmsTemplate;
   
   public void setJmsTemplate(JmsTemplate jmsTemplate){
    this.jmsTemplate = jmsTemplate;
   }
   
   public void sendMessage(final User user){
    //调用模板的send来发送消?br />     jmsTemplate.send(new MessageCreator(){
  
     public Message createMessage(Session session) throws JMSException {
      //构造一个要发送的消息
      MapMessage message = session.createMapMessage();
       message.setInt("id", user.getId());
       message.setString("username", user.getUsername());
       message.setString("password", user.getPassword());
       message.setString("email", user.getEmail());
      System.out.println("send success!!");
      return message;
     }
    });
   }
  }
  
 (3).消息消费者:(x)
  /**
   *  MessageConsumer.java
   *  created on Jul 22, 2006
   *  Copyrights 2006 BOCO,Inc. All rights reserved.
   */
  package com.boco.jms;
  
  import javax.jms.JMSException;
  import javax.jms.MapMessage;
  
  import org.springframework.jms.core.JmsTemplate;
  
  import com.boco.dto.User;
  
  /**
   * desc:消息消费?br />    * @author qiujy
   *
   */
  public class MessageConsumer {
   /** JMS模板 */
   private JmsTemplate jmsTemplate;
   
   public void setJmsTemplate(JmsTemplate jmsTemplate){
    this.jmsTemplate = jmsTemplate;
   }
   
   public User receiveMessage(){
    //参数为Destination的JNDI名字L前面的模式类型标?br />     //MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserQueue");
    MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserTopic");
    User user = new User();
    
    try {
     user.setId(msg.getInt("id"));
     user.setUsername(msg.getString("username"));
     user.setPassword(msg.getString("password"));
     user.setEmail(msg.getString("email"));
    } catch (JMSException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    
    return user;
   }
  }

 (4).试用例Q?br />    //======== 生者测试用?===============
   /**
   *  TestMsgProducer.java
   *  created on Jul 22, 2006
   *  Copyrights 2006 BOCO,Inc. All rights reserved.
   */
  package com.boco.jms;
  
  import junit.framework.TestCase;
  
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  
  import com.boco.dto.User;
  
  /**
   * desc:
   * @author qiujy
   *
   */
  public class TestMsgProducer extends TestCase {
  
   private ApplicationContext context;
   /**
    * @param arg0
    */
   public TestMsgProducer(String arg0) {
    super(arg0);
    context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");
   }
  
   /* (non-Javadoc)
    * @see junit.framework.TestCase#setUp()
    */
   protected void setUp() throws Exception {
    super.setUp();
   }
  
   /* (non-Javadoc)
    * @see junit.framework.TestCase#tearDown()
    */
   protected void tearDown() throws Exception {
    super.tearDown();
   }
  
   /**
    * Test method for {@link com.boco.jms.MessageProducer#sendMessage(com.boco.dto.User)}.
    */
   public void testSendMessage() {
    User user = new User();
    user.setId(132);
    user.setUsername("JMSTest");
    user.setPassword("password");
    user.setEmail("support@boco.com.cn");
    
    MessageProducer producer = (MessageProducer)context.getBean("msgProducer");
    
    producer.sendMessage(user);
    
   }
  
  }

  //============ 消费者测试用?===============
  /**
   *  TestMsgConsumer.java
   *  created on Jul 22, 2006
   *  Copyrights 2006 BOCO,Inc. All rights reserved.
   */
  package com.boco.jms;
  
  import junit.framework.TestCase;
  
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.support.ClassPathXmlApplicationContext;
  
  import com.boco.dto.User;
  
  /**
   * desc:
   * @author qiujy
   *
   */
  public class TestMsgConsumer extends TestCase {
   private ApplicationContext context;
   /**
    * @param arg0
    */
   public TestMsgConsumer(String arg0) {
    super(arg0);
    context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");
   }
  
   /* (non-Javadoc)
    * @see junit.framework.TestCase#setUp()
    */
   protected void setUp() throws Exception {
    super.setUp();
   }
  
   /* (non-Javadoc)
    * @see junit.framework.TestCase#tearDown()
    */
   protected void tearDown() throws Exception {
    super.tearDown();
   }
  
   /**
    * Test method for {@link com.boco.jms.MessageConsumer#receiveMessage()}.
    */
   public void testReceiveMessage() {
    MessageConsumer consumer = (MessageConsumer)context.getBean("msgConsumer");
    User user = consumer.receiveMessage();
    assertNotNull(user);
    System.out.println( "id========" + user.getId()
        + "\nname======" + user.getUsername()
        + "\npassword==" + user.getPassword()
        + "\nemail=====" + user.getEmail());
   }
  
  }

 


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1418938

启动JBOSS服务?先运行TestMsgConsumer.java;再运行TestMsgProducer.java,卛_看到控制台的输出?d~~~~~



KE 2008-01-15 21:00 发表评论
]]>
վ֩ģ壺 | ˮ| ɫ| ʯ| ǭ| | | | ɽ| | | | ӥ̶| | ˳| ˮ| | ɽ| | | Զ| | ն| | | | | ˮ| | | ʳ| ʻ| ̩| | | ɽ| ʯ| | ţ| | |