如何用Spring整和ActiveMQ?
来源:互联网 发布:协方差矩阵计算公式 编辑:程序博客网 时间:2024/05/17 03:53
问题一:为什么要整合ActiveMQ?
传统的JDBC代码在处理连接、语句、结果集和异常时是多么冗长和繁杂你一定不会忘记,传统的JMS继承了JDBC的“关荣传统”。发送一个简单的消息,要几行代码呢?请仔细数数吧。
Java代码
以下是引用片段:public void sendMessage() throws JMSException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"tcp://localhost:61616");
Connection connection = null;
Session session=null;
try {
connection = (Connection) connectionFactory.createConnection();//创建连接
session = (Session) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);//创建会话
Destination destination = session.createQueue("myQueue");
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage(expectedBody);
message.setStringProperty("headname", "remoteB");
producer.send(message);
connection.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(session!=null){
session.close();
}
if(connection!=null){
connection=null;
}
} catch (Exception e) {
}
}
}
public void sendMessage() throws JMSException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"tcp://localhost:61616");
Connection connection = null;
Session session=null;
try {
connection = (Connection) connectionFactory.createConnection();//创建连接
session = (Session) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);//创建会话
Destination destination = session.createQueue("myQueue");
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage(expectedBody);
message.setStringProperty("headname", "remoteB");
producer.send(message);
connection.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(session!=null){
session.close();
}
if(connection!=null){
connection=null;
}
} catch (Exception e) {
}
}
}
传统接受消息而是类似的代码,其实我们的目的就是发送和接受消息。幸运的是Spring为我们提供了大量的模板。项目一期用的较多的是JdbCTemplate,spring也为我们提供了JMSTemplate模板。
问题二:JMSTemplate模板该如何配置呢?
类似于jdbcTemplate,首先要配置一个ConnectionFactory,我们采用ActiveMQ5.2作为消息服务器。之后要开始配置JmsTemplate模板了。最后是配置消息目标了。消息分为队列和主题两大类,因此要配置两个消息目标了。
Java代码
以下是引用片段:<!-- ActiveMQ -->
<!-- 配置JMS连接工厂 -->
<bean id="JmsConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
</bean>
<!-- 发送消息的目的地(队列) -->
<bean id="QueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字 -->
<constructor-arg index="0" value="HelloWorldQueue"/>
</bean>
<!-- 发送消息的目的地(主题) -->
<bean id="TopicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<!-- 设置消息主题的名字 -->
<constructor-arg index="0" value="FlexTopic"/>
</bean>
<!-- ActiveMQ -->
<!-- 配置JMS连接工厂 -->
<bean id="JmsConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
</bean>
<!-- 发送消息的目的地(队列) -->
<bean id="QueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字 -->
<constructor-arg index="0" value="HelloWorldQueue"/>
</bean>
<!-- 发送消息的目的地(主题) -->
<bean id="TopicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<!-- 设置消息主题的名字 -->
<constructor-arg index="0" value="FlexTopic"/>
</bean>
问题三:如何使用JmsTemplate发送消息呢?
spring的beanfactory得到一个jmsTemplate的实例和消息目标的实例,发送消息,够简单的吧。看看代码:
Java代码
以下是引用片段:JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");
ActiveMQTopic destination=(ActiveMQTopic)SpringContext.getBean("TopicDestination");
template.send((javax.jms.Destination) destination, new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello");
}
});
JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");
ActiveMQTopic destination=(ActiveMQTopic)SpringContext.getBean("TopicDestination");
template.send((javax.jms.Destination) destination, new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello");
}
});
问题四:上面的代码能不能在简单些?
很多时候,发送消息的目标都是默认的,因此是不是可以在jmsTemplate中设置一个默认的消息目标呢?答案是肯定的。
Java代码
以下是引用片段:<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
</bean>
<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
</bean>
发送消息的时候,不指定目标,spring就会调用默认的目标了。
Java代码
以下是引用片段:JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");
template.send( new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello");
}
});
JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");
template.send( new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello");
}
});
问题四:jmsTemplate怎么接受信息?
jmsTemplate接收消息十分的简单,只需要调用template.receive()方法,receive方法是同步的,默认情况下,对receive()方法的调用会造成阻塞,知道消息到达目标----如果必要,永远等下去。为了避免对消息内容等待,可以配置jmsTemplate时,通过设置receiveTimeout属性来指定接收消息超时时间。下面的配置将接收消息的超时时间设置为一分钟(60000毫秒)。
Xml代码
以下是引用片段:<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
<property name="receiveTimeout" value="60000"></property>
</bean>
<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
<property name="receiveTimeout" value="60000"></property>
</bean>
template.receive()会从默认目标接收消息,如果你希望指定一个目标,可以传一个目标。如:template.receive("myQueue").
同步接收消息并不是spring唯一的选择,消息监听器可以实现异步(下篇文章将会介绍消息驱动)。
问题五:怎么自动将消息转化为Java对象?
转化器在很多组件中都是必不缺少的东西。Spring挺过MessageConverter接口提供了对消息转换的支持。
Java代码
以下是引用片段:public class MyMessageConverter implements MessageConverter {
@Override
public Object fromMessage(Message arg0) throws JMSException,
MessageConversionException {
// TODO Auto-generated method stub
return null;
}
@Override
public Message toMessage(Object arg0, Session arg1) throws JMSException,
MessageConversionException {
// TODO Auto-generated method stub
return null;
}
}
public class MyMessageConverter implements MessageConverter {
@Override
public Object fromMessage(Message arg0) throws JMSException,
MessageConversionException {
// TODO Auto-generated method stub
return null;
}
@Override
public Message toMessage(Object arg0, Session arg1) throws JMSException,
MessageConversionException {
// TODO Auto-generated method stub
return null;
}
}
MessageConverter接口的两个方法简单明了。在发送端toMessage会将java对象转化为消息,在接收端fromMessage会将消息转化为java对象。
下面的代码简单的实现了MessageConverter的两个接口。
以下是引用片段:Java代码
public class MyMessageConverter implements MessageConverter {
@Override
public Object fromMessage(Message message) throws JMSException,
MessageConversionException {
if(!(message instanceof MapMessage)){
throw new MessageConversionException("Messae is not MapMessage");
}
MapMessage mapMessage=(MapMessage)message;
MessageObj messageObj=new MessageObj();
messageObj.setId(mapMessage.getString("id"));
messageObj.setInfo(mapMessage.getString("info"));
return messageObj;
}
@Override
public Message toMessage(Object obj, Session session) throws JMSException,
MessageConversionException {
if(!(obj instanceof MessageObj)){
throw new MessageConversionException("obj is not MessageObj");
}
MessageObj messageObj=(MessageObj)obj;
MapMessage mapMessage=session.createMapMessage();
mapMessage.setString("id", messageObj.getId());
mapMessage.setString("info", messageObj.getInfo());
return mapMessage;
}
}
public class MyMessageConverter implements MessageConverter {
@Override
public Object fromMessage(Message message) throws JMSException,
MessageConversionException {
if(!(message instanceof MapMessage)){
throw new MessageConversionException("Messae is not MapMessage");
}
MapMessage mapMessage=(MapMessage)message;
MessageObj messageObj=new MessageObj();
messageObj.setId(mapMessage.getString("id"));
messageObj.setInfo(mapMessage.getString("info"));
return messageObj;
}
@Override
public Message toMessage(Object obj, Session session) throws JMSException,
MessageConversionException {
if(!(obj instanceof MessageObj)){
throw new MessageConversionException("obj is not MessageObj");
}
MessageObj messageObj=(MessageObj)obj;
MapMessage mapMessage=session.createMapMessage();
mapMessage.setString("id", messageObj.getId());
mapMessage.setString("info", messageObj.getInfo());
return mapMessage;
}
}
此时,发送和接收消息要换成template.convertAndSend(message);template.receiveAndConvert();
可是jmsTemplate如何知道消息转换器呢?需要在配置jmsTemplate的时候,加上messageConverter属性。
Java代码
以下是引用片段:<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
<property name="receiveTimeout" value="60000"></property>
<property name="messageConverter" ref="messageObj"></property>
</bean>
<!-- 配置JMS模版 -->
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="JmsConnectionFactory"/>
<property name="defaultDestination" ref="TopicDestination"></property>
<property name="receiveTimeout" value="60000"></property>
<property name="messageConverter" ref="messageObj"></property>
</bean>
messageObj是要转化的java对象的bean的id。
- 如何用Spring整和ActiveMQ?
- 如何用Spring整和ActiveMQ?
- 如何用Spring整和ActiveMQ?
- Spring整和ActiveMQ
- 如何用Spring 3.1的Environment和Profile简化工作
- 如何用Spring 3.1的Environment和Profile简化工作
- 如何用spring连接数据库
- 如何用Spring发送邮件
- ActiveMQ和spring整合
- ActiveMQ和spring集成
- Spring 和activemq集成
- ActiveMQ和spring整合
- Spring和ActiveMQ整合
- 如何用JUnit4测试spring service
- 如何用Spring读取JAR中的文件
- 如何用maven创建spring mvc项目
- 如何用Spring完成数据库的事物?
- 如何用Java类配置Spring MVC(不通过web.xml和XML方式)
- (整理+原创)windbg+vmware进行驱动源代码调试 转
- Java开发2.0:用Hadoop MapReduce进行大数据分析
- j2se 图形界面第一个程序helloworld (有图有真相)
- 三种常见的Java应用性能挑战
- abstract和virtual的区别
- 如何用Spring整和ActiveMQ?
- newInstance()方法和new关键字
- U-Boot编译系统简要分析
- c#枚举类型
- CentOS upgrade PHP
- warning C4482: 使用了非标准扩展: 限定名中使用了枚举
- 几种数据类型转换方法的区别
- 20120803 AIX_shell监控指定目录下是否有指定的文件名的文件生产
- 写一个程序,模拟4个售票窗口共同卖100张火车票的程序。