redis 入门——Spring 整合篇

2,503 阅读5分钟
原文链接: blog.csdn.net

redis入门——Spring整合篇

@(Redis)[服务器, 连接池, 集群, jedis, spring]

Spring整合Redis

redis整合分析

因为集群需要的服务器至少是6台,使用Redis集群的成本很高,所以如果没有业务要求,不会使用Redis集群。
而使用Redis集群的公司,为了节省成本,一般只会在生产环境使用集群,而开发环境使用Redis单机版,所以我们在整合项目的时候,单机版和集群版都要有。

我们可以创建一个接口,再编写单机版和集群版的实现类,使用spring进行管理,在部署时,使用哪种Redis,就切换那种实现类。

编写RedisUtils接口

package com.pc.redis;

/**
 * Redis工具接口
 * 
 * @author Switch
 * @data 2017年2月11日
 * @version V1.0
 */
public interface RedisUtils {
    /**
     * 保存
     * 
     * @param key
     *            键
     * @param value
     *            zhi
     */
    public void set(String key, String value);

    /**
     * 保存并设置生存时间
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param seconds
     *            时间,秒s为单位
     */
    public void set(String key, String value, Integer seconds);

    /**
     * 根据key查询
     * 
     * @param key
     *            键
     * @return 值
     */
    public String get(String key);

    /**
     * 删除
     * 
     * @param key
     *            键
     */
    public void del(String key);

    /**
     * 根据key设置生存时间
     * 
     * @param key
     *            键
     * @param seconds
     *            时间,秒s为单位
     */
    public void expire(String key, Integer seconds);

    /**
     * value加一<br/>
     * 注意key必须是整型
     * 
     * @param key
     *            键
     * @return 加一后的结果
     */
    public Long incr(String key);
}

编写RedisUtils实现类

单机版

package com.pc.redis.impl;

import org.springframework.beans.factory.annotation.Autowired;

import com.pc.redis.RedisUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * Redis连接池工具类
 * 
 * @author Switch
 * @data 2017年2月11日
 * @version V1.0
 */
public class RedisPool implements RedisUtils {
    @Autowired
    private JedisPool jedisPool;

    @Override
    public void set(String key, String value) {
        Jedis jedis = this.getJedis();
        jedis.set(key, value);
        this.releaseJedis(jedis);
    }

    @Override
    public void set(String key, String value, Integer seconds) {
        Jedis jedis = this.getJedis();
        jedis.set(key, value);
        jedis.expire(key, seconds);
        this.releaseJedis(jedis);
    }

    @Override
    public String get(String key) {
        Jedis jedis = this.getJedis();
        String result = jedis.get(key);
        this.releaseJedis(jedis);
        return result;
    }

    @Override
    public void del(String key) {
        Jedis jedis = this.getJedis();
        jedis.del(key);
        this.releaseJedis(jedis);
    }

    @Override
    public void expire(String key, Integer seconds) {
        Jedis jedis = this.getJedis();
        jedis.expire(key, seconds);
        this.releaseJedis(jedis);
    }

    @Override
    public Long incr(String key) {
        Jedis jedis = this.getJedis();
        Long count = jedis.incr(key);
        this.releaseJedis(jedis);
        return count;
    }

    /**
     * 获取Jedis连接
     * 
     * @return Jedis连接
     */
    public Jedis getJedis() {
        return this.jedisPool.getResource();
    }

    /**
     * 释放Jedis连接
     * 
     * @param jedis
     *            jedis连接
     */
    public void releaseJedis(Jedis jedis) {
        jedis.close();
    }
}

集群版

package com.pc.redis.impl;

import org.springframework.beans.factory.annotation.Autowired;

import com.pc.redis.RedisUtils;

import redis.clients.jedis.JedisCluster;

/**
 * Redis集群工具类
 * 
 * @author Switch
 * @data 2017年2月11日
 * @version V1.0
 */
public class RedisCluster implements RedisUtils {
    @Autowired
    private JedisCluster jedisCluster;

    @Override
    public void set(String key, String value) {
        this.jedisCluster.set(key, value);
    }

    @Override
    public void set(String key, String value, Integer seconds) {
        this.jedisCluster.set(key, value);
        this.jedisCluster.expire(key, seconds);
    }

    @Override
    public String get(String key) {
        return this.jedisCluster.get(key);
    }

    @Override
    public void del(String key) {
        this.jedisCluster.del(key);
    }

    @Override
    public void expire(String key, Integer seconds) {
        this.jedisCluster.expire(key, seconds);
    }

    @Override
    public Long incr(String key) {
        return this.jedisCluster.incr(key);
    }

    /**
     * 获取JedisCluster对象<br/>
     * 可以直接使用它来进行redis操作
     * 
     * @return JedisCluster对象
     */
    public JedisCluster getJedisCluster() {
        return jedisCluster;
    }
}

配置Spring管理Redis

创建applicationContext-redis.xml

一般来书,spring配置文件分类之后,会将下面的配置放在applicationContext-dao.xml配置文件中。

<!-- 配置 读取properties文件 -->
<context:property-placeholder location="classpath:resource/*.properties" />

注意:使用的时候开启一个配置即可。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        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.xsd">

    <!-- 两种方案:使用jedis连接池(单机版)和jedis集群 -->
    <!-- 一般生产环境使用集群,开发环境使用单机版 -->
    <!-- 使用哪种,可以将另一种注释掉 -->
    <!-- 注意:如果在注入工具类的时候是按类型注入的话,那么不使用的工具类必须注释掉-->

    <!-- 单机版 -->
    <!-- 配置jedis连接池 -->
    <bean class="redis.clients.jedis.JedisPool">
        <constructor-arg name="host" value="${redis.host}" />
        <constructor-arg name="port" value="${redis.port}" />
    </bean>

    <!-- 配置单机版工具类 -->
    <bean class="com.pc.redis.impl.RedisPool" />


    <!-- 集群版 -->
    <!-- 配置jedis集群 -->
    <bean class="redis.clients.jedis.JedisCluster">
        <constructor-arg name="nodes">
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host1}" />
                    <constructor-arg name="port" value="${cluster.port1}" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host2}" />
                    <constructor-arg name="port" value="${cluster.port2}" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host3}" />
                    <constructor-arg name="port" value="${cluster.port3}" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host4}" />
                    <constructor-arg name="port" value="${cluster.port4}" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host5}" />
                    <constructor-arg name="port" value="${cluster.port5}" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="${cluster.host6}" />
                    <constructor-arg name="port" value="${cluster.port6}" />
                </bean>
            </set>
        </constructor-arg>
    </bean>

    <!-- 配置集群版工具类 -->
    <bean class="com.pc.redis.impl.RedisCluster" />
</beans>

添加redis.properties

#redis单机版信息
redis.host=192.168.37.131
redis.port=6379


#redis集群版信息
cluster.host1=192.168.37.131
cluster.port1=7001

cluster.host2=192.168.37.131
cluster.port2=7002

cluster.host3=192.168.37.131
cluster.port3=7003

cluster.host4=192.168.37.131
cluster.port4=7004

cluster.host5=192.168.37.131
cluster.port5=7005

cluster.host6=192.168.37.131
cluster.port6=7006

redis用作缓存

添加缓存的步骤

  1. 从缓存中命中
  2. 没有命中执行原有逻辑,从数据库MySQL中查询
  3. 把数据保存在redis

添加缓存的原则

不能够影响正常的业务逻辑,可以进行try/catch

package com.pc.test;

import org.springframework.beans.factory.annotation.Autowired;

import com.pc.redis.RedisUtils;

/**
 * 缓存测试类
 * 
 * @author Switch
 * @data 2017年2月11日
 * @version V1.0
 */
public class RedisCacheTest {
    // 注入Redis工具类
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public String queryByRedis() {
        String key = "redis";
        // 1.从缓存中命中
        try {
            String redisJson = redisUtils.get(key);
            if (StringUtils.isNotBlank(redisJson)) {
                return redisJson;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 2.如果没用命中,执行原有逻辑,从数据库中获取数据
        // 未实现,从数据库中获取数据
        String json = getFromDB();

        // 3.将查询出来的结果加入缓存
        try {
            this.redisUtils.set(key, json);
            this.redisUtils.expire(key, 60 * 60 * 24);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }
}