银行卡消费的时候,银行每每会经过微信、短信或邮件通知用户交易的详细信息,这即是发布订阅模式。 咱们能够使用下面的命令进行模拟redis
先打开一个客户端1,输入命令spring
SUBSCRIBE chat
表示客户端1订阅一个名为chat的渠道,以后打开客户端2,输入命令微信
publish chat "Hello World!"
在Spring中,咱们自定义接收消息的类,须要实现MessageListener接口,并实现接口定义的方法onMessage,代码以下。app
public class RedisMessageListener implements MessageListener { @SuppressWarnings("rawtypes") private RedisTemplate rt; @SuppressWarnings("rawtypes") public RedisTemplate getRt() { return rt; } @SuppressWarnings("rawtypes") public void setRt(RedisTemplate rt) { this.rt = rt; } @Override public void onMessage(Message message, byte[] pattern) { // 获取消息 byte[] body = message.getBody(); // 使用值序列化器转换 String msgBody = (String)getRt().getValueSerializer().deserialize(body); System.out.println(msgBody); // 获取channel byte[] channel = message.getChannel(); // 使用字符串序列化器转换 String channelStr = (String)getRt().getStringSerializer().deserialize(channel); System.out.println(channelStr); // 渠道名称转换 String bytesStr = new String(pattern); System.out.println(bytesStr); } }
这里咱们没有使用注解,因此要去spring.xml中注册beanide
<!-- 实例化类 --> <bean id="redisMsgListener" class="com.codeliu.transaction.RedisMessageListener"> <property name="rt" ref="redisTemplate"></property> </bean>
实例化监听类以后还不行,还得给一个监听容器,在Spring中对应的类为RedisMessageListenerContainer,它能够用来监听Redis的发布订阅消息。一样在Spring.xml中进行配置测试
<!-- 配置监听容器 --> <bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy"> <!-- redis链接工厂 --> <property name="connectionFactory" ref="connectionFactory"></property> <!-- 链接池,只有线程池生存,才能继续监听 --> <property name="taskExecutor"> <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"> <property name="poolSize" value="3"></property> </bean> </property> <!-- 消息监听map --> <property name="messageListeners"> <map> <!-- 配置监听者,key-ref与bean id保持一致 --> <entry key-ref="redisMsgListener"> <!-- 监听类 --> <bean class="org.springframework.data.redis.listener.ChannelTopic"> <constructor-arg value="chat"></constructor-arg> </bean> </entry> </map> </property> </bean>
这里配置了线程池,这个线程池将会持续的生存以等待消息传入,而这里配置了容器用id为redisMsgListener的Bean进行渠道chat的监听。当消息经过渠道chat方法的时候,就会使用id为redisMsgListener的Bean处理消息。this
下面进行测试线程
public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); RedisTemplate rt = applicationContext.getBean(RedisTemplate.class); String channel = "chat"; // 向渠道chat发送消息 rt.convertAndSend(channel, "Hello World!"); }
convertAndSend方法就是向指定的渠道发送消息。code
输出xml
Hello World! chat chat