SpringBoot基于Redis实现简单的发布订阅功能

1、前言

  正如标题所言,在SpringBoot项目中,基于Redis实现了简单的订阅和发布功能。项目实例地址:https://gitee.com/hsh2015/learningDemo/tree/master/redis-learning。下面主要记录一下,在实现该实例用到的知识点。

2、依赖文件
  <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>
3、启动类和Redis配置

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;
   }
4、定义发布者

定义发布者,代码如下:

使用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" );
    }
}
5、定义订阅者

使用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;
    }
}
6、测试

首先定义一个测试类,通过接口调用发布者,传递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,在控制台就会打印出来如下内容:
SpringBoot基于Redis实现简单的发布订阅功能_第1张图片

你可能感兴趣的:(Redis,Spring,redis,pub/sub,订阅发布,生产者消费者)