Maven dependency
maven的dependency用着 隐形的依赖传递性,如果只是用到 JMS这部分功能 引用一下Maven坐标即可
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${project.dependency.spring.core}</version> </dependency>
依赖传递关系,可见SpringJMS 会隐形的导入其他的依赖包
Spring Namespace
Spring-config.xml 支持 Spring-jms的命名空间,使用namespace 可以简化spring的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd"> <!-- bean definitions here --> </beans>
Spring beans
使用 Spring JMS 最基本的需要构建2个类, 一个是JMS Template 一个是JMS 客户端
- JMS Template: 是Spring 自身提供,只需向Spring 容器内 注册这个类即可
- JMS 客户端 : 这个是需要自己编写的, 会使用到JMS Template类,如果需要 spring 托管 也需要向容器内 注册
构建JMS 客户端类
使用@Service 注解将 类注册到spring 容器中, 使用Autowire注解 自动装填 JMS Template。
定义 JmsTemplate的setter方法 主要是为了解耦,脱离spring 容器的时候 需要自行set 一个 JMS template 实例
@Service("JMSDemo") public class JMSDemo{ private JmsTemplate jmsTemplate; @Autowired public void setJmsTempalte(JmsTemplate jmsTemplate){ this.jmsTemplate = jmsTemplate; } public void send(final String argQueueName, final Serializable argObject) throws JMSException { jmsTemplate.send(argQueueName, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createObjectMessage(argObject); } }); } public Message consumee(String queueName) throws JMSException { Message message = jmsTemplate.receive(queueName); return message; } }
Spring Config
spring的配置文件中 首先需要 componet-scan 去扫描package 将带有@component @Service 等注解的类 注册到spring的容器中。
<!-- =============================================== --> <!-- component Scanning --> <!-- =============================================== --> <context:component-scan base-package="com.*"/>
其次需要需要定义 Jms template Bean
Jms Template 需要额外配置 connectionFactory 和defaultDestination 属性 messageConverter 是可选项,后面后续的系列会提到。
这里使用了 spring的 cacheConnectionFactory去池化connection。
最终 我们需要向spring 提供 2个实现类 分别是 connectionFacotry和defaultDestination
<!-- =============================================== --> <!-- JMS Template --> <!-- =============================================== --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="cachingConnectionFactory"/> <property name="defaultDestination" ref="jmsDestination"/> <property name="messageConverter"> <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/> </property> </bean> <!-- Pooled Spring connection factory --> <bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <property name="targetConnectionFactory" ref="jmsConnectionFactory" /> </bean>
如果需要到 JNID 里面去寻找 JMS 供应 使用 jee:jndi-lookup 去寻找即可
前提是 需要加上 jee 的name space
xmlns:jee=" xsi:schemaLocation=" http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="amqConnectionFactory" /> <jee:jndi-lookup id="jmsDestination" jndi-name="amqDestination" />
如果需要到 自己定义实现类 需要额外定义 connectFactory 的实际类(各供应商可能各不相同),这里以ActiveMQ为例
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <!-- brokerURL, You may have different IP or port --> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="defaultDestination" class="org.apache.activemq.command.ActiveMQQueue"> <!--<property name="compositeDestinations" value="testQueue"/>--> <constructor-arg index="0" value="testQueue" /> </bean>
测试
简单测试 发送消息到队列
准备工作需要 引入依赖包 ActiveMq 和Spring-test 和 开启 JMS服务器
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>${project.dependency.apache.activemq}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${project.dependency.spring.core}</version> <scope>test</scope> </dependency>
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); // creates an JNDI Context and combine resources SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); builder.bind("amqConnectionFactory", connectionFactory); builder.bind("amqDestination", new ActiveMQQueue("testQueue") ); // Initialize Spring Context ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); JMSDemo jmsDemo = context.getBean(JMSDemo.class); jmsDemo.send("testQueue",new object());