Redis的发布订阅在SpringMVC(或xml配置)项目中使用(注意版本兼容问题)

在Spring中使用 Redis ,除了需要 jedis.jar 外,还需要下载 spring-data-redis.jar,打开网址 https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis , 

注意 spring5以上需要配置 spring-data-redis 2.0

基于spring主版本为4.3.13.RELEASE的项目,测试以下对应版本可用。

spring-data-redis版本

jedis版本

备注

1.5.2.RELEASE

2.7.3

1.6.0.RELEASE

2.7.2  2.7.3

1.6.2.RELEASE

2.8.0

1.8.1.RELEASE

2.9.0

1.8.4.RELEASE

2.9.0

项目中使用的版本:

spring-data-redis-1.6.6.RELEASE.jar   jedis-2.9.0.jar

项目结构

 

1、客户端(订阅):

redis.properties

#redis pool config
redis.pool.maxActive=1000
redis.pool.maxIdle=100
redis.pool.maxWaitMillis=10000
redis.pool.testOnBorrow=true

#redis config
redis.host=192.168.0.198
redis.port=6379
redis.timeout=6000
redis.password=123456
redis.dbindex=8
redis.usePool=1
redis.default.expire=1800000
redis.topicName=message

 applicationContext-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<description>Redis configuration</description>

	<!-- 载入redis配置参数 -->
<!--	<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true" />-->

	<!-- redis config start -->
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.pool.maxIdle}"></property>
		<property name="maxTotal" value="${redis.pool.maxActive}" />
		<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
		<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
		<!-- <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"></property>
			<property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"></property>
			<property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"></property>
		-->
	</bean>

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		destroy-method="destroy">
		<property name="poolConfig" ref="jedisPoolConfig"></property>
		<property name="hostName" value="${redis.host}"></property>
		<property name="port" value="${redis.port}"></property>
		<property name="password" value="${redis.password}"></property>
		<property name="timeout" value="${redis.timeout}"></property>
		<!--是否使用連接池 <property name="usePool" value="${redis.usePool}"></property> -->
	</bean>

	<!-- redis操作模板,面向对象的模板 -->
	<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
	<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
	<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
		<!-- 如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 -->
		<!-- 注意:原来valueSerializer配置为jdkSerializationRedisSerializer , 实际测试取值时会出现类似内容: \xac\xed\x00\x05t\x00\tb ,需要改成stringRedisSerializer    -->
		<property name="keySerializer" ref="stringRedisSerializer" />
		<property name="valueSerializer" ref="stringRedisSerializer" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
		<property name="keySerializer">
			<bean
				class="org.springframework.data.redis.serializer.StringRedisSerializer" />
		</property>
		<property name="valueSerializer">
			<bean
				class="org.springframework.data.redis.serializer.StringRedisSerializer">
			</bean>
		</property>
	</bean>
    <!-- redis config end -->

	<!-- Redis 发布订阅监配置 -->
	<!-- 1、配置监听类 -->
	<bean id="redisMessageListener" class="com.gy.xf.listener.RedisMessageListener">
		<property name="stringRedisTemplate" ref="redisTemplate"></property>
	</bean>
	<!-- 2、配置监听容器 -->
	<bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy">
		<!-- redis连接工厂 -->
		<property name="connectionFactory" ref="jedisConnectionFactory"></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="redisMessageListener">
					<!-- 监听类 -->
					<bean class="org.springframework.data.redis.listener.ChannelTopic" >
						<constructor-arg value="${redis.topicName}"></constructor-arg>
					</bean>
				</entry>
			</map>
		</property>
	</bean>




</beans>

RedisMessageListener.java

package com.gy.xf.listener;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gy.xf.entity.redis.AlarmInfo;
import com.gy.xf.util.RedisCacheUtils;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * Redis 发布订阅监听类
 */
public class RedisMessageListener implements MessageListener {

    private Logger logger = LoggerFactory.getLogger(RedisMessageListener.class);

//    @Autowired
    private StringRedisTemplate stringRedisTemplate;// = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");


    //初始化JSON解析器
    public ObjectMapper mapper = new ObjectMapper();

    @Override
    public void onMessage(Message message, byte[] bytes) {
        //获取消息
        byte[] body = message.getBody();
        //使用值序列化器转换
        String msgBody = (String) stringRedisTemplate.getValueSerializer().deserialize(body);
        //获取channel
//        byte[] channel = message.getChannel();
//        String channelName = (String) stringRedisTemplate.getValueSerializer().deserialize(channel);

        //渠道名称转换
//        String bytesStr = new String(bytes);
        //logger.info("Redis监听消息:直接获取渠道名称 = " + bytesStr);
        logger.info("警情处理(Redis缓存): 本条消息处理开始.................................");
        AlarmInfo model = JSON.parseObject(msgBody , AlarmInfo.class);
        if (null != model){
            //判断groupId是否在专职队单位id表中
            String groupIdList = RedisCacheUtils.getStr(RedisCacheUtils.KEY_ALARM_GROUPIDS);
            if (!StringUtils.isEmpty(groupIdList)){
                if(groupIdList.indexOf(model.getGroupId())!=-1){
                    String alarmKey = RedisCacheUtils.KEY_ALARM_GROUPID_PREFIX + model.getGroupId();
                    RedisCacheUtils.set(alarmKey , model.getUploadId() , RedisCacheUtils.KEY_ALARM_TIMEOUT);//0 或 null 标示永不不超时
                    logger.info("警情处理(Redis缓存): 将专职队调派信息写入缓存。groupId:{} , uploadId:{} " , new Object[]{
                          model.getGroupId() , model.getUploadId()
                    });
                }else{
                    logger.info("警情处理(Redis缓存): 非专职队调派信息,不处理!!!groupId:{} , uploadId:{} " , new Object[]{
                                model.getGroupId() , model.getUploadId()
                    });
//                    if(model.getGroupId().indexOf(groupIdList)!=-1){
//                        logger.info("警情处理(缓存): 非专职队调派信息,不处理。groupId:{} , uploadId:{} " , new Object[]{
//                                model.getGroupId() , model.getUploadId()
//                        });
//                    }
                }
            }else{
                logger.error("警情处理(Redis缓存): 读取专职队单位id缓存数据不存在,请检查!!!");
            }
        }
        logger.info("警情处理(Redis缓存): 本条消息处理完毕.................................");
    }

    /**
     * 发送消息
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
     * @return
     * @throws Exception

    public void sendMessage(String sysId, String postData) {
        try {
            String access_token = CacheUtils.getStr(CacheUtils.KEY_WX_ACCESS_TOKEN);
            if (StringUtils.isEmpty(access_token)){
                logger.error("Redis监听消息:发送消息,获取 access_token 失败,数据不存在, sysId = {} " , sysId);
            }
            //拼接url
            String url = Constants.GET_TEMPLATE_MESSAGE_PREFIX + "access_token=" + access_token;
            //请求返回结果
            WxRequestReult result = null;
            //请求地址
            //logger.info("发送模板消息给用户 , 请求url = " + url);
            CloseableHttpClient httpClient = HttpClients.custom().build();

            //创建post请求及设置参数
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
            StringEntity stringEntity = new StringEntity(postData , Constants.UTF_8);
            httpPost.setEntity(stringEntity);
            //发送请求
            CloseableHttpResponse response = httpClient.execute(httpPost);
            //设置 post  参数
            final int statusCode = response.getStatusLine().getStatusCode();
            int code = HttpStatus.SC_OK;
            HttpEntity entity = response.getEntity();
            //处理数据
            if (code == statusCode && entity != null) {
                result = mapper.readValue(EntityUtils.toString(entity) , WxRequestReult.class);
                response.close();
                httpClient.close();
            }

            logger.info("Redis监听消息:发送消息 ,  sysId = {} , 请求结果 = {}" , sysId , mapper.writeValueAsString(result) );
            //如果访问失败了则返回 null

        } catch (Exception e){
            e.printStackTrace();
            logger.info("Redis监听消息:发送消息 , sysId = {} , 出现异常 = {}" , sysId , e.getMessage());
        }

    }
     */


    public StringRedisTemplate getStringRedisTemplate() {
        return stringRedisTemplate;
    }

    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
}

RedisCacheUtils.java

package com.gy.xf.util;

import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis 缓存工具类
 */
public class RedisCacheUtils {

    /** Redis 发布订阅模式: 与redis配置文件的redis.topicName一致 */
    public static final String REDIS_CHANNEL_NAME = "message";

    /** 固定token:  16位 , Aes加密作为 key 参数 */
    public static final String CSRFTOKEN = "fireoms2021kqxlr";

    /**
     * app端登录用户用户唯一id  token key 前缀
     */
    public static final String USER_ID_TOKEN_KEY_PREFIX = "user:lid_";
    /**
     * app端登录用户  token key 前缀
     */
    public static final String USER_TOKEN_KEY_PREFIX = "user:u_";


    /**
     * app端消息推送用户 token key 前缀
     */
    public static final String PUSH_TOKEN_KEY_PREFIX = "push:u_";


    //登录用户过期时间(7天后)
    public static final long TOKEN_EXPIRE_TIME_USER = 7 * 24 * 60 * 60;//(用户过期时间)

    //单位id列表
    public static final String KEY_ALARM_GROUPIDS = "alarm:groupIds";
    //单位警情数据前缀
    public static final String KEY_ALARM_GROUPID_PREFIX = "alarm:groupId_";
    //redis中key的超时时间
    public static final long KEY_ALARM_TIMEOUT = 12 * 60 * 60;//单位为秒,2小时(7200秒)

    /** --------------------- 微信公众平台:Redis 参数 --------------------- */
    //redis中key的超时时间
    public static final long KEY_WX_TIMEOUT = 7200;//单位为秒,2小时
    //公众号中访问access_token: 2小时过期
    public static final String KEY_WX_ACCESS_TOKEN = "wx:access_token";
    //公众号网页开发中的jsapi中请求的票据:2小时过期
    public static final String KEY_WX_TICKET = "wx:ticket";
    //接收公众号消息数据
    public static final String KEY_WX_USER_PREFIX = "wx:u_";

    /**
     * 生成签名及判断签名是否相同
     */
    public static boolean isEqualsSignData(String clientSignData, String data){
        String signData = MD5.Md5(data);
        if (clientSignData.equals(signData)){
            return true;
        }
        return false;
    }


    /** redis操作模板,面向对象的模板 */
    private static StringRedisTemplate stringRedisTemplate
            = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");
    private static RedisTemplate<String, Object> redisTemplate
            = (RedisTemplate) SpringUtil.getBean("redisTemplate");

    /**
     * 删除缓存<br>
     * 根据key精确匹配删除
     *
     * @param key
     */
    @SuppressWarnings("unchecked")
    public static void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * (根据key精确匹配删除)
     * @param key
     */
    public static void deleteByKey(String  key) {
        if (key != null) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 批量删除<br>
     * (该操作会执行模糊查询,请尽量不要使用,以免影响性能或误删)
     *
     * @param pattern
     */
    public void batchDel(String... pattern) {
        for (String kp : pattern) {
            redisTemplate.delete(redisTemplate.keys(kp + "*"));
        }
    }

    /**
     * 取得缓存(int型)
     *
     * @param key
     * @return
     */
    public  Integer getInt(String key) {
        String value = stringRedisTemplate.boundValueOps(key).get();
        if (StringUtils.isNotEmpty(value)) {
            return Integer.valueOf(value);
        }
        return null;
    }

    /**
     * 取得缓存(字符串类型)
     *
     * @param key
     * @return
     */
    public static String getStr(String key) {
        return stringRedisTemplate.boundValueOps(key).get();
    }

    /**
     * 取得缓存(字符串类型)
     *
     * @param key
     * @return
     */
    public static String getStr(String key, boolean retain) {
        String value = stringRedisTemplate.boundValueOps(key).get();
        if (!retain) {
            redisTemplate.delete(key);
        }
        return value;
    }

    /**
     * 模糊查询(根据规则) 返回 keys
     * @param pattern
     * @return
     */
    public static Set<String> searchKeys(String pattern){
       return stringRedisTemplate.keys(pattern);
    }


    /**
     * 获取缓存<br>
     * 注:基本数据类型(Character除外),请直接使用get(String key, Class<T> clazz)取值
     *
     * @param key
     * @return
     */
    public static Object getObj(String key) {
        return redisTemplate.boundValueOps(key).get();
    }

    /**
     * 获取缓存<br>
     * 注:java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
     *
     * @param key
     * @param retain
     *            是否保留
     * @return
     */
    public  Object getObj(String key, boolean retain) {
        Object obj = redisTemplate.boundValueOps(key).get();
        if (!retain) {
            redisTemplate.delete(key);
        }
        return obj;
    }

    /**
     * 获取缓存<br>
     * 注:该方法暂不支持Character数据类型
     *
     * @param key
     *            key
     * @param clazz
     *            类型
     * @return
     */
    @SuppressWarnings("unchecked")
    public  <T> T get(String key, Class<T> clazz) {

        return (T) redisTemplate.boundValueOps(key).get();
    }

    /**
     * 获取缓存json对象<br>
     *
     * @param key
     *            key
     * @param clazz
     *            类型
     * @return
     * @throws Exception

    @SuppressWarnings("unchecked")
    public  <T> T getJson(String key, Class<T> clazz) throws Exception {
        String jsonStr=null;
        jsonStr=stringRedisTemplate.boundValueOps(key).get();
        if(jsonStr==null){
            return null;
        }else{
            return (T) JsonUtil.jsonToBean(jsonStr, clazz);
        }
    } */

    /**
     * 将value对象写入缓存
     *
     * @param key
     * @param value
     * @param time
     *            失效时间(秒)
     */
    public static void set(String key, Object value, Long time) {
        if (value.getClass().equals(String.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Integer.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Double.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Float.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Short.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Long.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else if (value.getClass().equals(Boolean.class)) {
            stringRedisTemplate.opsForValue().set(key, value.toString());
        } else {
            redisTemplate.opsForValue().set(key, value);
        }
        if (time != null && time > 0) {
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
            stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }

    /**
     * 将value对象以JSON格式写入缓存
     *
     * @param key
     * @param value
     * @param time
     *            失效时间(秒)

    public  void setJson(String key, Object value, Long time) {
        stringRedisTemplate.opsForValue().set(key, JsonUtil.toJsonString(value));
        if (time!=null&&time > 0) {
            stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }
     */

    /**
     * 更新key对象field的值
     *
     * @param key
     *            缓存key
     * @param field
     *            缓存对象field
     * @param value
     *            缓存对象field值

    public  void setJsonField(String key, String field, String value) {
        JSONObject obj = JSON.parseObject(stringRedisTemplate.boundValueOps(key).get());
        obj.put(field, value);
        stringRedisTemplate.opsForValue().set(key, obj.toJSONString());
    }
     */

    /**
     * 递减操作
     *
     * @param key
     * @param by
     * @return
     */
    public  double decr(String key, double by) {
        return redisTemplate.opsForValue().increment(key, -by);
    }

    /**
     * 递增操作
     *
     * @param key
     * @param by
     * @return
     */
    public  double incr(String key, double by) {
        return redisTemplate.opsForValue().increment(key, by);
    }

    /**
     * 获取double类型值
     *
     * @param key
     * @return
     */
    public  double getDouble(String key) {
        String value = stringRedisTemplate.boundValueOps(key).get();
        if (StringUtils.isNotBlank(value)) {
            return Double.valueOf(value);
        }
        return 0d;
    }

    /**
     * 设置double类型值
     *
     * @param key
     * @param value
     * @param time
     *            失效时间(秒)
     */
    public  void setDouble(String key, double value, Long time) {
        stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
        if (time!=null&&time > 0) {
            stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }

    /**
     * 设置double类型值
     *
     * @param key
     * @param value
     * @param time
     *            失效时间(秒)
     */
    public  void setInt(String key, int value, Long time) {
        stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
        if (time!=null&&time > 0) {
            stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }

    /**
     * 将map写入缓存
     *
     * @param key
     * @param map
     * @param time
     *            失效时间(秒)
     */
    public  <T> void setMap(String key, Map<String, T> map, Long time) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * 将map写入缓存
     *
     * @param key
     * @param map
     * @param time
     *            失效时间(秒)

    @SuppressWarnings("unchecked")
    public  <T> void setMap(String key, T obj, Long time) {
        Map<String, String> map = (Map<String, String>)JsonUtil.parseObject(obj, Map.class);
        redisTemplate.opsForHash().putAll(key, map);
    }
     */

    /**
     * 向key对应的map中添加缓存对象
     *
     * @param key
     * @param map
     */
    public  <T> void addMap(String key, Map<String, T> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * 向key对应的map中添加缓存对象
     *
     * @param key
     *            cache对象key
     * @param field
     *            map对应的key
     * @param value
     *            值
     */
    public  void addMap(String key, String field, String value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    /**
     * 向key对应的map中添加缓存对象
     *
     * @param key
     *            cache对象key
     * @param field
     *            map对应的key
     * @param obj
     *            对象
     */
    public  <T> void addMap(String key, String field, T obj) {
        redisTemplate.opsForHash().put(key, field, obj);
    }

    /**
     * 获取map缓存
     *
     * @param key
     * @param clazz
     * @return

    public  <T> Map<String, T> mget(String key, Class<T> clazz) {
        BoundHashOperations<String, String, T> boundHashOperations = redisTemplate.boundHashOps(key);
        return boundHashOperations.entries();
    }*/

    /**
     * 获取map缓存中的某个对象
     *
     * @param key
     * @param field
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public  <T> T getMapField(String key, String field, Class<T> clazz) {
        return (T) redisTemplate.boundHashOps(key).get(field);
    }

    /**
     * 获取map缓存
     *
     * @param key
     * @param clazz
     * @return

    public  <T> T getMap(String key, Class<T> clazz) {
        BoundHashOperations<String, String, String> boundHashOperations = redisTemplate.boundHashOps(key);
        Map<String, String> map = boundHashOperations.entries();
        return JsonUtil.parseObject(map, clazz);
    } */

    /**
     * 删除map中的某个对象
     *
     * @author lh
     * @date 2016年8月10日
     * @param key
     *            map对应的key
     * @param field
     *            map中该对象的key
     */
    public void delMapField(String key, String... field) {
        BoundHashOperations<String, String, ?> boundHashOperations = redisTemplate.boundHashOps(key);
        boundHashOperations.delete(field);
    }

    /**
     * 指定缓存的失效时间
     *
     * @author FangJun
     * @date 2016年8月14日
     * @param key
     *            缓存KEY
     * @param time
     *            失效时间(秒)
     */
    public  void expire(String key, Long time) {
        if (time!=null&&time > 0) {
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }

    /**
     * 添加set
     *
     * @param key
     * @param value
     */
    public  void sadd(String key, String... value) {
        redisTemplate.boundSetOps(key).add(value);
    }

    /**
     * 删除set集合中的对象
     *
     * @param key
     * @param value
     */
    public  void srem(String key, String... value) {
        redisTemplate.boundSetOps(key).remove(value);
    }

    /**
     * set重命名
     *
     * @param oldkey
     * @param newkey
     */
    public  void srename(String oldkey, String newkey) {
        redisTemplate.boundSetOps(oldkey).rename(newkey);
    }




    /**
     * 短信缓存
     *
     * @author fxl
     * @date 2016年9月11日
     * @param key
     * @param value
     * @param time

    public  void setIntForPhone(String key, Object value, int time) {
        stringRedisTemplate.opsForValue().set(key, JsonUtil.toJsonString(value));
        if (time > 0) {
            stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
        }
    }
     */

    /**
     * 模糊查询keys
     *
     * @param pattern
     * @return
     */
    public static Set<String> keys(String pattern) {

        return redisTemplate.keys(pattern);
    }

    /**
     *
     * @Description (检查key是否存在,返回boolean值 )
     * @author feizhou
     * @Date 2018年5月29日下午5:37:40
     * @version 1.0.0
     * @param key
     * @return
     */
    public  Boolean   ishasKey(String key) {
        return stringRedisTemplate.hasKey(key);
    }

}

SpringUtil.java

package com.gy.xf.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 工具类 - Spring
 * @author zgp2010
 *
 */

public class SpringUtil implements ApplicationContextAware {
	
	private static ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		SpringUtil.applicationContext = applicationContext;
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 根据Bean名称获取实例
	 * 
	 * @param name
	 *            Bean注册名称
	 * 
	 * @return bean实例
	 * 
	 * @throws BeansException
	 */
	public static Object getBean(String name) throws BeansException {
		return applicationContext.getBean(name);
	}
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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:context="http://www.springframework.org/schema/context"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:jee="http://www.springframework.org/schema/jee"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd" >

	<!--
	    tomcat中context.xml配置的jndi名字
	    <bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    		<property name="jndiName" value="java:comp/env/jdbc/MSSQLDS"></property>
    	</bean>
    	<bean name="new_dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    		<property name="jndiName" value="java:comp/env/jdbc/MSSQLDSALARM"></property>
    	</bean>
    	jboss中的配置:
    	<bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    		<property name="jndiName" value="MSSQLDS"></property>
    	</bean>
    	<bean name="new_dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    		<property name="jndiName" value="MSSQLDSALARM"></property>
    	</bean>
	 -->

	<bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    	 <property name="jndiName" value="java:comp/env/jdbc/MSSQLDS"></property>
    </bean>
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource"><ref bean="dataSource" /></property>
	</bean>
	<bean name="new_dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" >
    	 <property name="jndiName" value="java:comp/env/jdbc/MSSQLDSALARM"></property>
    </bean>
    <bean id="newjdbcTemple" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="new_dataSource"/>
    </bean>
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource"><ref bean="dataSource" /></property>
	</bean>
	<bean id="dataSourceTransactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource"><ref bean="dataSource" /></property>
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />



	<!-- 添加spring工具类 -->
	<bean id="springUtil" class="com.gy.xf.util.SpringUtil" lazy-init="false" />


	<!--
	  导入配置文件 config.properties 、redis.properties
	  注意:如果项目中有多个属性文件,要合并在一起加载同一管理。如果分散在不同的配置文件中,只能按文件顺序加载第一个配置文件中的属性文件。
	  <context:property-placeholder location="classpath*:config.properties"></context:property-placeholder>
	-->

	<context:property-placeholder location="classpath*:*.properties"></context:property-placeholder>

    <!-- 普通后台管理 -->
    <import resource="com/gy/xf/spring/spring-admin.xml" />
   

	<!-- EhCache缓存注解配置(系统配置)  -->
	<cache:annotation-driven cache-manager="springCacheManager" proxy-target-class="false"/>
	<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:ehcache-settings.xml"/>
		<property name="shared" value="true"></property>
 	</bean>
	<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="ehcacheManager"/>
	</bean>


	<!-- Redis 数据缓存 2022-07-22 -->
	<import resource="applicationContext-redis.xml"></import>

</beans>

2、服务端(发布):
 

说明:服务端和客户端的redis连接参数都是一样的,这里不再重复贴出配置文件。

服务端发布内容,用到的是 redisTemplate中的 convertAndSend(String channel, Object message) 方法。只要服务端和客户端配置的channel名字是一样的,服务端发送客户端订阅了就能收到。

/** Redis 发布订阅模式: 与redis配置文件的redis.topicName一致 */
public static final String REDIS_CHANNEL_NAME = "message";

public void convertAndSend(String channel, Object message) {
        Assert.hasText(channel, "a non-empty channel is required");
        final byte[] rawChannel = this.rawString(channel);
        final byte[] rawMessage = this.rawValue(message);
        this.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection) {
                connection.publish(rawChannel, rawMessage);
                return null;
            }
        }, true);
    }

实际用法,在控制器类中或工具类中 注入 RedisTemplate类 或者 StringRedisTemplate 类,在需要发布消息的地方执行 convertAndSend 方法即可。

  AlarmInfo model = new AlarmInfo(groupId , uploadId);
  String postData = JSON.toJSONString(model);
  logger.info("地理信息系统调派专职队车辆,参数:{}" , postData);
  stringRedisTemplate.convertAndSend(RedisCacheUtils.REDIS_CHANNEL_NAME , postData);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值