Spring boot集成Activemq
使用Spring boot和Activemq集成,可以使用默认的ActiveMQAutoConfiguration类加载properties文件的配置。同时也可以自己写代码实现或者是xml配置文件实现Activemq的配置。
使用Spring boot的AutoConfig加载
新建Spring boot工程
登录http://start.spring.io/ ,在Dependencies中输入Activemq并选择,然后点击Generate Project生成工程,将下载的Maven工程导入Eclipse等开发工具即可。
pom文件依赖的jar包
如果是使用连接池需要用到activemq-pool,否则只要spring-boot-starter-activemq就可以实现activemq的消息发送接收。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!--如果使用连接池需要用到 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
配置application.properties:
spring.activemq.broker-url=failover:(tcp://119.29.80.40:61616,tcp://119.29.80.50:61616)?timeout=3000&randomize=false
#用户名
spring.activemq.user=activemq-admin
#密码
spring.activemq.password=admin@user
#所有的包是否安全
spring.activemq.packages.trust-all=true
#启用连接池
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50
spring.activemq.pool.expiry-timeout=10000
spring.activemq.pool.idle-timeout=30000
spring.activemq.pool.session-cache-size=100
生产者:
@Component
public class JMSProducer {
@Autowired
@Qualifier("jmsTemplate")
private JmsTemplate jmsTemplate;
/**
* 发送消息
* @Description:
* @param destination
* @param vo
*/
public void sendMessage(final Destination destination,final MessageVo vo) {
this.jmsTemplate.convertAndSend(destination,vo);
}
}
消费者:
@Component
public class JMSConsumer {
private final static Logger logger = LoggerFactory.getLogger(JMSConsumer.class);
@JmsListener(destination = "springboot.queue.test")
public void receiveQueue(MessageVo message) {
logger.info("接收到消息:{}",message.toString());
}
}
配置完成后,启动,可以在Activemq的控制台看到注册的queue,有一个消费者
写一个测试类来发送消息:
新建一个叫“springboot.queue.test”的消息队列Destination,通过jmsTemplate.convertAndSend发送到目的地。
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootActivemqApplicationTests {
@Autowired
private JMSProducer jmsProducer;
@Test
public void contextLoads() {
Destination destination = new ActiveMQQueue("springboot.queue.test");
MessageVo vo=new MessageVo();
for (int i=0;i<10;i++) {
vo.setName("name"+i);
vo.setValue("value"+i);
jmsProducer.sendMessage(destination,vo);
}
}
}
自己写代码加载配置
spring boot加载Activemq配置的源码
可以看到spring-boot-autoconfigure的源代码中是使用ActiveMQAutoConfiguration来加载Activemq的配置的。 其中ActiveMQConnectionFactoryConfiguration会加载properties文件的前缀为“spring.activemq.pool”的属性。
@Configuration
@AutoConfigureBefore(JmsAutoConfiguration.class)
@AutoConfigureAfter({ JndiConnectionFactoryAutoConfiguration.class })
@ConditionalOnClass({ ConnectionFactory.class, ActiveMQConnectionFactory.class })
@ConditionalOnMissingBean(ConnectionFactory.class)
@EnableConfigurationProperties(ActiveMQProperties.class)
@Import({ ActiveMQXAConnectionFactoryConfiguration.class,
ActiveMQConnectionFactoryConfiguration.class })
public class ActiveMQAutoConfiguration {
}
@Configuration
@ConditionalOnMissingBean(ConnectionFactory.class)
class ActiveMQConnectionFactoryConfiguration {
@Bean
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
public ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
return new ActiveMQConnectionFactoryFactory(properties,
factoryCustomizers.getIfAvailable())
.createConnectionFactory(ActiveMQConnectionFactory.class);
}
@ConditionalOnClass(PooledConnectionFactory.class)
static class PooledConnectionFactoryConfiguration {
@Bean(destroyMethod = "stop")
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
@ConfigurationProperties(prefix = "spring.activemq.pool.configuration")
public PooledConnectionFactory pooledJmsConnectionFactory(
ActiveMQProperties properties,
ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(
new ActiveMQConnectionFactoryFactory(properties,
factoryCustomizers.getIfAvailable()).createConnectionFactory(
ActiveMQConnectionFactory.class));
ActiveMQProperties.Pool pool = properties.getPool();
pooledConnectionFactory.setBlockIfSessionPoolIsFull(pool.isBlockIfFull());
pooledConnectionFactory
.setBlockIfSessionPoolIsFullTimeout(pool.getBlockIfFullTimeout());
pooledConnectionFactory
.setCreateConnectionOnStartup(pool.isCreateConnectionOnStartup());
pooledConnectionFactory.setExpiryTimeout(pool.getExpiryTimeout());
pooledConnectionFactory.setIdleTimeout(pool.getIdleTimeout());
pooledConnectionFactory.setMaxConnections(pool.getMaxConnections());
pooledConnectionFactory.setMaximumActiveSessionPerConnection(
pool.getMaximumActiveSessionPerConnection());
pooledConnectionFactory
.setReconnectOnException(pool.isReconnectOnException());
pooledConnectionFactory.setTimeBetweenExpirationCheckMillis(
pool.getTimeBetweenExpirationCheck());
pooledConnectionFactory
.setUseAnonymousProducers(pool.isUseAnonymousProducers());
return pooledConnectionFactory;
}
}
}
自己通过代码方式实现加载:
@Configuration
public class ActiveMqConfig {
/**
* 连接工厂
* @Description:
* @param brokerURL
* @param userName
* @param password
* @param sessionCacheSize
* @return
*/
@Bean(name = "connectionFactory")
@Primary
public ConnectionFactory connectionFactory(
@Value("${spring.activemq.broker-url}") String brokerURL,
@Value("${spring.activemq.user}") String userName,
@Value("${spring.activemq.password}") String password,
@Value("${spring.activemq.pool.session-cache-size}")Integer sessionCacheSize) {
ActiveMQConnectionFactory factory=new ActiveMQConnectionFactory(userName, password, brokerURL);
factory.setTrustAllPackages(true);
factory.setUseAsyncSend(true);
CachingConnectionFactory cachingFactory=new CachingConnectionFactory(factory);
cachingFactory.setSessionCacheSize(sessionCacheSize);
return cachingFactory;
}
/**
* jms模板
* @Description:
* @param connectionFactory
* @return
*/
@Bean(name = "jmsTemplate")
@Primary
public JmsMessagingTemplate jmsTemplate(
@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
JmsMessagingTemplate firstTemplate = new JmsMessagingTemplate(connectionFactory);
return firstTemplate;
}
}
使用xml配置文件加载
对于大多数之前使用xml文件配置的同学,还想沿用xml文件配置Activemq,只要在application中引入xml文件即可。
@ImportResource(locations={"classpath:spring/spring-activemq.xml"})
@SpringBootApplication
public class SpringBootActivemqApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootActivemqApplication.class, args);
}
}
<bean id="connectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="sessionCacheSize" value="100" />
<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.brokerURL}" />
<property name="userName" value="${activemq.user}" />
<property name="password" value="${activemq.passwd}" />
<!-- 安全的包 -->
<property name="trustAllPackages" value="true"/>
<!--异步发送 -->
<property name="useAsyncSend" value="true" />
</bean>
</property>
</bean>
<!-- jms事务 -->
<bean id="jmsTransactionManager"
class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<tx:annotation-driven transaction-manager="jmsTransactionManager" />
<!--jms模板 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--队列地址 -->
<bean id="testDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="springboot.queue.test"/>
</bean>
<!--消费者配置 -->
<bean id="jmsConsumer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="testDestination" />
<property name="messageListener" ref="testMsgListener" />
<!--jms事务 -->
<property name="transactionManager" ref="jmsTransactionManager" />
<!-- 应答模式是 INDIVIDUAL_ACKNOWLEDGE-->
<property name="sessionAcknowledgeMode" value="4"></property>
<property name="idleConsumerLimit" value="10" />
<property name="concurrency" value="30-100" />
</bean>