java关于redis实现publish/subscribe二三事

设计模式:订阅模式,发现redis也有频道订阅的功能,简单尝试了下:上代码

需要的工具:jedis(maven依赖导入)

  <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.7.2</version>
    </dependency>

1配置文件spring-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	<!--开启注解扫描  -->
	<context:component-scan base-package="add"></context:component-scan>
	
	<!-- 配置单机版的连接 -->
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<constructor-arg name="host" value="${redis}"></constructor-arg>
		<constructor-arg name="port" value="${redis-port}"></constructor-arg>
	</bean>
	<bean id="jedisClientPool" class="com.zc.service.JedisClientPool" />

</beans>

jedis工具抽象类JedisClient

package com.zc.service;

import java.util.List;

public interface JedisClient {

	String set(String key, String value);

	String get(String key);

	Boolean exists(String key);

	Long expire(String key, int seconds);

	Long ttl(String key);

	Long incr(String key);

	Long hset(String key, String field, String value);

	String hget(String key, String field);

	Long hdel(String key, String... field);

	Long del(String key);

	Long repush(String key, String strings);

	List<String> lrange(String key);

	Long set(String key, boolean flg);

	Long publish(String channel, String message);

	void subscribe(String channel);
}

实现类JedisClientPool(由于有依赖注入,配置里面扫描记得扫描这里,同时我发布和订阅都是在一个工程里面,所以publis和subscribe方法都写了)

package com.zc.service;

import com.zc.utils.RedisMsgPubSub;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.List;


public class JedisClientPool implements JedisClient {

    @Resource
    private JedisPool jedisPool;

    @Resource
    private RedisMsgPubSub redisListener;


    @Override
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.set(key, value);
        jedis.close();
        return result;
    }

    @Override
    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        jedis.close();
        return result;
    }

    @Override
    public Long del(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.del(key);
        jedis.close();
        return result;
    }

    @Override
    public Boolean exists(String key) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.exists(key);
        jedis.close();
        return result;
    }

    @Override
    public Long expire(String key, int seconds) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.expire(key, seconds);
        jedis.close();
        return result;
    }

    @Override
    public Long ttl(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.ttl(key);
        jedis.close();
        return result;
    }

    @Override
    public Long incr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.incr(key);
        jedis.close();
        return result;
    }

    @Override
    public Long hset(String key, String field, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(key, field, value);
        jedis.close();
        return result;
    }

    @Override
    public String hget(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.hget(key, field);
        jedis.close();
        return result;
    }

    @Override
    public Long hdel(String key, String... field) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hdel(key, field);
        jedis.close();
        return result;
    }

    @Override
    public Long repush(String key, String strings) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.rpush(key, strings);
        jedis.close();
        return result;
    }

    @Override
    public List<String> lrange(String key) {
        Jedis jedis = jedisPool.getResource();
        List<String> result = jedis.lrange(key, 0, -1);
        jedis.close();
        return result;
    }

    @Override
    public Long set(String key, boolean flg) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.bitpos(key, flg);
        jedis.close();
        return result;
    }

    @Override
    public Long publish(String channel, String message) {
        // TODO Auto-generated method stub
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.publish(channel, message);
        jedis.close();
        return result;
    }

    @Override
    public void subscribe(String channel) {
        Jedis jedis = jedisPool.getResource();
        //RedisMsgPubSub listener = new RedisMsgPubSub();
        jedis.subscribe(redisListener, channel);
        jedis.close();
    }
}

1发布(我是写了controller 来发布消息)RedisController

package com.zc.controller;

import com.zc.dto.ResultDto;
import com.zc.service.JedisClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;


@Controller
@RequestMapping("/redis")
public class RedisController {
    private final Logger logger  = LoggerFactory.getLogger(this.getClass());
    @Resource
    private JedisClient jedis;
    @RequestMapping("/preJedisPublish")
    public String preJedisPublish(){
        return "jedisPublish";
    }
    @ResponseBody
    @RequestMapping("/jedisPublish")
    public ResultDto jedisPublish(String message){
        ResultDto result = new ResultDto();
        try {
            jedis.publish("redisMessage",message);
            //模拟起见,直接在初始化时就订阅固定频道,具体使用见机行事
            result.setMessage("success");
            result.setSuccess(true);
        }catch (Exception e){
            logger.error("jedisPublish error ::,{}",e);
            result.setSuccess(false);
            result.setMessage("false");
        }
        return result;
    }
}

到这发布功能就完了

2订阅

1>.绑定频道方法ThreadRedisRead

package com.zc.utils.Thread;

import com.zc.service.JedisClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class ThreadRedisRead implements Runnable {
    @Resource
    private JedisClient jedis;
    @Override
    public void run() {
        jedis.subscribe("redisMessage");
    }
}

2>绑定方法已在前工具类中写了

3>根据消息的不同处理类(根据实际需要)RedisMsgPubSub

package com.zc.utils;

import com.zc.initConstructor.InitData;
import com.zc.utils.Thread.RedisThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPubSub;

@Component
public class RedisMsgPubSub extends JedisPubSub {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Override
	public void unsubscribe() {
		super.unsubscribe();
	}

	@Override
	public void unsubscribe(String... channels) {
		super.unsubscribe(channels);
	}

	@Override
	public void subscribe(String... channels) {
		super.subscribe(channels);
	}

	@Override
	public void psubscribe(String... patterns) {
		super.psubscribe(patterns);
	}

	@Override
	public void punsubscribe() {
		super.punsubscribe();
	}

	@Override
	public void punsubscribe(String... patterns) {
		super.punsubscribe(patterns);
	}

	/*
	 * (non-Javadoc) channal订阅的频道 s robot开关 A 活跃度
	 */
	@Override
	public void onMessage(String channel, String message){
		logger.debug("channel:" + channel + " receives message :" + message);
		//具体操作的地方
		String content = message.substring(1,message.length());
		RedisThread ss = RedisThread.getInstance();
		if(message.startsWith("0")){
			InitData.setJedisFlag(true);
			InitData.setJedisMessage(content);
			ss.run();
		}else if(message.startsWith("1")) {
			InitData.setJedisFlag(false);
		}else{
			return;
		}
	}

	@Override
	public void onPMessage(String pattern, String channel, String message) {

	}

	@Override
	public void onSubscribe(String channel, int subscribedChannels) {
		// System.out.println("channel:" + channel + "is been subscribed:" +
		// subscribedChannels);
	}

	@Override
	public void onPUnsubscribe(String pattern, int subscribedChannels) {

	}

	@Override
	public void onPSubscribe(String pattern, int subscribedChannels) {

	}

	@Override
	public void onUnsubscribe(String channel, int subscribedChannels) {
		// System.out.println("channel:" + channel + "is been unsubscribed:" +
		// subscribedChannels);
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值