正如标题所言,在SpringBoot项目中,基于Redis实现了简单的订阅和发布功能。项目实例地址:https://gitee.com/hsh2015/learningDemo/tree/master/redis-learning。下面主要记录一下,在实现该实例用到的知识点。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
dependencies>
application.yml配置:
server:
port: 8008
servlet:
context-path: /qriver-redis1
tomcat:
uri-encoding: UTF-8
# 数据库连接
spring:
redis:
host: 127.0.0.1
database: 0
port: 6379
password: 123456
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: 1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 1000 # 连接超时时间(毫秒)
#日志(log4j2)
logging:
#log4j2-dev.yml
config: classpath:logback.xml
启动类:
@SpringBootApplication
public class QriverApplication {
public static void main(String[] args) {
SpringApplication.run(QriverApplication.class, args);
}
}
Redis配置类:
主要通过配置的方式注入了RedisTemplate实例。
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
//key序列化
RedisSerializer keySerializer = new StringRedisSerializer();
RedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(keySerializer);
//value序列化
redisTemplate.setValueSerializer(valueSerializer);
//hash key 序列化
redisTemplate.setHashKeySerializer(keySerializer);
//hash value 序列化
redisTemplate.setHashValueSerializer(valueSerializer);
//redis初始化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisTemplate<String, Object> redisTemplateGroup(RedisConnectionFactory factory) {
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
RedisSerializer keySerializer = new StringRedisSerializer();
RedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer(getMapper());
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setValueSerializer(valueSerializer);
redisTemplate.setHashKeySerializer(keySerializer);
redisTemplate.setHashValueSerializer(valueSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 获取JSON工具
* @return
*/
private final ObjectMapper getMapper() {
ObjectMapper mapper = new ObjectMapper();
//将类名称序列化到json串中,去掉会导致得出来的的是LinkedHashMap对象,直接转换实体对象会失败
//设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
//其中该配置,需要升级fasterxml版本
//mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
定义发布者,代码如下:
使用Redis实现的发布,其实就是通过redisTemplate.convertAndSend()方法实现。
@Component
public class MsgPublisher {
private Logger logger = LoggerFactory.getLogger(MsgPublisher.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private ChannelTopic topic;
public void sendMsg(String msg){
redisTemplate.convertAndSend( topic.getTopic(), "Message: " + msg +
";Time:" + Calendar.getInstance().getTime());
}
}
发布者配置:
主要定义了一个发布者的主题,该主题可以直接在MsgPublisher类中通过new方法创建。
@Configuration
public class PubConfig {
/**
* 订阅发布的主题
* @return
*/
@Bean
ChannelTopic topic() {
return new ChannelTopic( "pubsub:queue" );
}
}
使用Redis实现的订阅者,需要两个步骤:第一,定义消息监听器,需要实现MessageListener接口,第二,需要配置RedisMessageListenerContainer容器,即把消息监听器添加到容器中。
监听器:
主要是实现了MessageListener 接口的onMessage()方法,该方法即是用来处理监听结果的代码块(这里只是简单的打印到控制台)。
@Component
public class MsgListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println( "Message received: " + message.toString() );
}
}
订阅者配置(容器):
主要定义了RedisMessageListenerContainer 容器,并把监听器放到容器中,并添加监听器监听的主题。
@Configuration
public class SubConfig {
@Bean
MessageListenerAdapter messageListener() {
return new MessageListenerAdapter( new MsgListener() );
}
@Bean
RedisMessageListenerContainer redisContainer(RedisConnectionFactory factory) {
final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
container.addMessageListener(messageListener(), new ChannelTopic( "pubsub:queue" ));
return container;
}
}
首先定义一个测试类,通过接口调用发布者,传递msg参数,然后订阅者可以监听到该参数并打印到控制台:
@Controller
public class RedisTestController {
@Autowired
private MsgPublisher msgPublisher;
@RequestMapping("/sendMsg")
@ResponseBody
public String sendMsg(@RequestParam("msg") String msg){
msgPublisher.sendMsg(msg);
return "发送成功!";
}
}
然后,通过QriverApplication启动类,启动系统后,在浏览器中访问http://localhost:8008/qriver-redis1/sendMsg?msg=hello,world,在控制台就会打印出来如下内容: