1.maven 中导入 activeMQ的依赖
- 导入 activeMQ-all 的依赖
注:导入activemq 所有的 依赖jar包 ,可能会导致项目中jar 冲突,可能有的同学会说 可以排除冲突的jar。经过本人尝试 发现 排除不了 activemq-all 中的冲突的 jar ,原因是 activemq-all pom中的使用了 “maven-shade-plugin” 插件(直接将所有的依赖 打成了一个 jar 包) 导致 exclusion 无效。<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.15.0</version> </dependency>
2.根据项目而定 导入activeMQ相关的jar包
<!--jms activeMQ-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-openwire-legacy</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-pool2</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
<exclusion>
<artifactId>activemq-spring</artifactId>
<groupId>org.apache.activemq</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jaas</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-databind</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-console</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-pool</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-http</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-mqtt</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-stomp</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jdbc-store</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-leveldb-store</artifactId>
<version>5.15.0</version>
<classifier>sources</classifier>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>leveldbjni</artifactId>
<groupId>org.fusesource.leveldbjni</groupId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq.protobuf</groupId>
<artifactId>activemq-protobuf</artifactId>
<version>1.1</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.fusesource.hawtbuf</groupId>
<artifactId>hawtbuf</artifactId>
<version>1.11</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_1.1_spec</artifactId>
<version>1.1.1</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-j2ee-management_1.1_spec</artifactId>
<version>1.0.1</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-annotation_1.0_spec</artifactId>
<version>1.1.1</version>
<classifier>sources</classifier>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!--jms activeMQ end-->
注:我在 active-all上去掉了 一些日志的jar包 ,和不需要用的 jar包
2 配置 spring-jms xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<!--jms 注解驱动-->
<jms:annotation-driven ></jms:annotation-driven>
<!--activeMQ的连接工厂-->
<bean id="activeMQConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
<property name="userName" value="admin"></property>
<property name="password" value="admin"></property>
<property name="brokerURL" value="tcp://192.168.0.131:61616"></property>
</bean>
<!--destination-resolver 目标资源 -->
<bean id="dynamicDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver">
</bean>
<bean id="jmsReceiveListener" class="com.hua.fileplat.cloud.base.jms.JmsReceiveListener"></bean>
<!--消息队列-->
<jms:listener-container
factory-id="jmsFactory"
connection-factory="activeMQConnectionFactory"
destination-resolver="dynamicDestinationResolver"
destination-type="queue"
response-destination-type="queue"
receive-timeout="3000"
>
<jms:listener destination="dynamicDestinationResolver" ref="jmsReceiveListener"></jms:listener>
</jms:listener-container>
<bean id="jmsTemplate" name="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="activeMQConnectionFactory"></property>
<!--如果没有使用JTA,对于上面的配置如果把属性 sessionTransacted 设成true jms事务与 数据库事务融合-->
<property name="sessionTransacted" value="true"></property>
</bean>
</beans>
注 : 我这里简单的实现了 消息队列 接收消息侦听和 JMS事务
- 侦听器容器中的 client-id 属性 是用于 订阅模式下的 属性
- sessionTransacted=true 是让 JMS事务 融合到 spring 事务中,这样 就可以和数据库 事务一起配合是用。
2 侦听器实例
发送消息
package com.hua.fileplat.cloud.user.service;
import com.hua.fileplat.cloud.user.dao.RoleDao;
import com.hua.fileplat.cloud.user.dto.RoleDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import java.util.Date;
import java.util.List;
/**
* 角色服务
*/
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleDao roleDao;
@Override
public List<RoleDto> selectRole() {
return roleDao.selectRole();
}
@Autowired
public JmsTemplate jmsTemplate;
/**
* 嵌套回滚 https://www.cnblogs.com/duanxz/p/4746892.html
* @return
*/
@Override
@Transactional
public boolean transactionTest1() {
List<RoleDto> roleDtoList=selectRole();
RoleDto roleDto= roleDtoList.get(0);
/*try{
transactionTest2(roleDto);
}catch (Exception e){
}finally {
System.out.println(roleDto.getId());
}*/
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append("hahha1sssssss");
stringBuffer.append(new Date().getTime());
roleDto.setName(stringBuffer.toString());
roleDao.updateRoleDto(roleDto);
return false;
}
/**
* 嵌套回滚 https://www.cnblogs.com/duanxz/p/4746892.html
* @return
*/
@Override
@Transactional
public boolean transactionTest() {
List<RoleDto> roleDtoList=selectRole();
RoleDto roleDto= roleDtoList.get(0);
/*try{
transactionTest2(roleDto);
}catch (Exception e){
}finally {
System.out.println(roleDto.getId());
}*/
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append("hahha");
stringBuffer.append(new Date().getTime());
roleDto.setName(stringBuffer.toString());
roleDao.updateRoleDto(roleDto);
int i=2/0;
return false;
}
@Transactional(propagation = Propagation.REQUIRED)
public boolean transactionTest2(RoleDto roleDto){
roleDto.setId("888888");
int i=2/0;
return false;
}
@Override
@Transactional
public boolean jmsTransactionTest() {
MessageCreator messageCreator=new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
Message message=session.createMessage();
message.setStringProperty("hello","hello,Jms");
return message;
}
};
jmsTemplate.send("dynamicDestinationResolver",messageCreator);
transactionTest();
return false;
}
}
接收消息侦听器
package com.hua.fileplat.cloud.base.jms;
import com.hua.fileplat.cloud.user.service.RoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.transaction.annotation.Transactional;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
/**
* JSM 接收消息侦听
*/
public class JmsReceiveListener implements SessionAwareMessageListener {
@Autowired
private RoleService roleService;
/**
* 日志
*/
Logger logger= LoggerFactory.getLogger(JmsReceiveListener.class);
@Override
@Transactional
public void onMessage(Message message, Session session) {
try {
logger.info("接收消息内容为:"+message.getStringProperty("hello"));
roleService.transactionTest1();
int i=10/0;
}catch (JMSException e){
e.printStackTrace();
logger.error("接收消息异常编号:"+e.getErrorCode()+" 异常信息:"+e.getMessage());
try {
session.rollback();
} catch (JMSException e1) {
logger.error(" 事务异常信息:"+e.getMessage());
}
}
}
}
注:
- 如果 发送消息 所在的方法 出现了 异常 那么 消息不会被发送出去
- 如果 接收消息 出现了异常 ,那么 事务也会回滚,数据库也不会执行更新操作