說明
最近來寫幾個使用SpringBoot下會遇到的多數據源的接入問題以及處理方式吧~。
在實際的項目中,我們經常會需要接入或者發給很多不同的MQ,那麼在Springboot下有什麼比較好的處理方式?噹噹噹,AMQP(Advanced Message Queuing Protocol 高級消息隊列協議)來啦,這是一個提供統一消息服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同的開發語言等條件的限制。簡單來說這個協議野心比較大(ง •_•)ง,他想要市面上的MQ去按照這個協議標準去開發,那麼對於我們開發者來說,接入不同的MQ的成本就會比較低了,然而現在只有RabbitMQ遵循了這個協議。。。所以如果項目使用的是RabbitMQ的開發者可以考慮使用這個AMQP的包來處理多源問題。
快速開始
首先當然要引入包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
然後在配置文件application.yml裏填MQ地址(假設有兩個MQ待接入,如果是測試的話可以通過不同virtual-host的方式來測試,virtual-host不同就相當於多個不同的MQ了)
spring:
rabbitmq:
# 多源配置
outside:
port: 5672
username: yunlingfly
password: password
host: xxx.xxx.xxx.xxx
virtual-host: /
inside:
port: 5672
username: test
password: test
host: xxx.xxx.xxx.xxx
virtual-host: test
編寫Java配置文件
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.annotation.Resource;
/**
* rabbitMQ多源配置
*
* @author : yunlingfly
* @date : 2020/1/9
*/
@Configuration
public class RabbitMqConfig {
@Bean(name = "insideConnectionFactory")
@Primary
public ConnectionFactory insideConnectionFactory(
@Value("${spring.rabbitmq.inside.host}") String host,
@Value("${spring.rabbitmq.inside.port}") int port,
@Value("${spring.rabbitmq.inside.username}") String username,
@Value("${spring.rabbitmq.inside.password}") String password,
@Value("${spring.rabbitmq.inside.virtual-host}") String virtualHost) {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(host);
connectionFactory.setPort(port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
return connectionFactory;
}
@Bean(name = "outsideConnectionFactory")
public ConnectionFactory outsideConnectionFactory(
@Value("${spring.rabbitmq.outside.host}") String host,
@Value("${spring.rabbitmq.outside.port}") int port,
@Value("${spring.rabbitmq.outside.username}") String username,
@Value("${spring.rabbitmq.outside.password}") String password,
@Value("${spring.rabbitmq.outside.virtual-host}") String virtualHost) {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(host);
connectionFactory.setPort(port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
return connectionFactory;
}
@Bean(name = "insideRabbitTemplate")
@Primary
public RabbitTemplate firstRabbitTemplate(@Qualifier("insideConnectionFactory") ConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
@Bean(name = "outsideRabbitTemplate")
public RabbitTemplate secondRabbitTemplate(@Qualifier("outsideConnectionFactory") ConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
@Bean(name = "insideContainerFactory")
public SimpleRabbitListenerContainerFactory insideSyncFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer,
@Qualifier("insideConnectionFactory") ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
@Bean(name = "outsideContainerFactory")
public SimpleRabbitListenerContainerFactory outsideFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer,
@Qualifier("outsideConnectionFactory") ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
}
那麼如何使用呢(多源同理接收或發送改@RabbitListener裏的containerFactory或者@Resource裏的name即可)->
// 接收使用containerFactory指定源
@RabbitListener(queues = "hello", containerFactory="insideContainerFactory")
public void receiver(String data) {
System.out.println(data);
}
// 發送使用Resource指定源
@Resource(name="insideRabbitTemplate")
private RabbitTemplate insideRabbitTemplate;
private void sendMsgToMQ() {
insideRabbitTemplate.convertAndSend("queueName", "msg");
}