本指南将指导您完成使用Spring Data Redis发布和订阅通过Redis发送的消息的过程。你将了解redis安装,及做消息队列方法,并明白如何在程序中使用。
Springboot官方例子–使用Redis做消息队列服务
程序结构
└── src
└── main
└── java
└── hello
pom.xml文件
4.0.0
org.springframework
gs-messaging-redis
0.1.0
org.springframework.boot
spring-boot-starter-parent
2.1.6.RELEASE
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-maven-plugin
Spring Boot将会你做如下的事:
将 classpath 里面所有用到的jar包构建成一个可执行的 JAR 文件,方便执行你的程序
搜索public static void main()方法并且将它当作可执行类
根据springboot版本,去查找相应的依赖类版本,当然你可以定义其它版本。
启动Redis服务器
在构建消息传递应用程序之前,需要设置处理接收和发送消息的Redis服务器。
Redis是一个开源的、BSD许可的、key-value的数据存储服务器,它还附带了一个消息传递系统。服务器可以在https://redis.io/download上免费使用。您可以手动下载,也可以在自制的Mac上使用brew:
brew install redis:
解包Redis后,可以使用默认设置启动它。
redis-server
您应该看到这样的消息:
[35142] 01 May 14:36:28.939 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[35142] 01 May 14:36:28.940 * Max number of open files set to 10032
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 2.6.12 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in stand alone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 35142
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
[35142] 01 May 14:36:28.941 # Server started, Redis version 2.6.12
[35142] 01 May 14:36:28.941 * The server is now ready to accept connections on port 6379
创建redis消息接收器
在任何基于消息的应用程序中,都有消息发布者和消息接收者。要创建消息接收者,请使用响应消息的方法实现接收者:
src/main/java/hello/Receiver.java
package hello;
import java.util.concurrent.CountDownLatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class Receiver {
private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
private CountDownLatch latch;
@Autowired
public Receiver(CountDownLatch latch) {
this.latch = latch;
}
public void receiveMessage(String message) {
LOGGER.info("Received <" + message + ">");
latch.countDown();
}
}
接收器是一个简单的POJO,它定义了接收消息的方法。正如您将接收器注册为消息侦听器时看到的,您可以根据需要命名消息处理方法。
出于演示目的,它由具有CountDownLatch latch参数的构造函数自动装配。这样,它可以在收到消息时发出信号。
注册侦听器并发送消息
Spring Data Redis提供了使用Redis发送和接收消息所需的所有组件。具体来说,您需要配置:
您将使用redis模板发送消息,并将接收器注册到消息侦听器容器,以便它接收消息。连接工厂将驱动模板和消息侦听器容器,使它们能够连接到Redis服务器。
此示例使用Spring Boot的默认RedisConnectionFactory,它是基于jedis redis库的jedisconnectionFactory实例。连接工厂被注入到消息侦听器容器和redis模板中。
src/main/java/hello/Application.java
package hello;
import java.util.concurrent.CountDownLatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
@SpringBootApplication
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
Receiver receiver(CountDownLatch latch) {
return new Receiver(latch);
}
@Bean
CountDownLatch latch() {
return new CountDownLatch(1);
}
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
CountDownLatch latch = ctx.getBean(CountDownLatch.class);
LOGGER.info("Sending message...");
template.convertAndSend("chat", "Hello from Redis!");
latch.await();
System.exit(0);
}
}
listenerAdapter方法中定义的bean被注册作容器中消息侦听器,并将侦听“chat”主题上的消息。因为receiver类是一个POJO,
所以它需要包装在一个消息侦听器适配器中,该适配器实现addMessageListener()所需的MessageListener接口。
消息侦听器适配器还配置为在消息到达时调用接收器上的receiveMessage()方法。
您需要连接工厂和消息侦听器容器beans来侦听消息。要发送消息,还需要redis模板。在这里它是一个配置为StringRedisTemplate的bean,它是RedisTemplate的一个实现,主要关注redis的常见用法,其中键和值都是String。
main()方法通过创建一个Spring应用程序上下文来启动一切。然后,应用程序上下文启动消息侦听器容器,消息侦听器容器bean开始侦听消息。
然后,main()方法从应用程序上下文中检索StringRedisTemplate bean,并使用它发送“Hello from Redis!”关于“chat”主题的消息。最后,它关闭Spring应用程序上下文并结束应用程序。
运行你的程序(STS下,Maven可参考前面文章)
你会看见如下的输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
2014-04-18 08:03:34.032 INFO 47002 --- [ main] hello.Application : Starting Application on retina with PID 47002 (/Users/gturnquist/src/spring-guides/gs-messaging-redis/complete/target/classes started by gturnquist)
2014-04-18 08:03:34.062 INFO 47002 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchy
2014-04-18 08:03:34.326 INFO 47002 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Started Application in 0.605 seconds (JVM running for 0.899)
2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Sending message...
2014-04-18 08:03:34.370 INFO 47002 --- [ container-2] hello.Receiver : Received
2014-04-18 08:03:34.379 INFO 47002 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchy
2014-04-18 08:03:34.380 INFO 47002 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647
我利用业余时间,翻译了Spring官网的例子,方便中文不好的同学,将陆续发到CSDN上,欢迎大家关注,也可以上我个人BLOG:itmanclub.com,上面有已经翻译过的。