使用Spring + Jedis集成Redis

一、集成环境

Tomcat7

JDK1.7

Jedis-2.7.2

Spring-4.1.6

二、资源依赖

(省略,网上很多)

三、集成过程

1、配置资源池

这里使用Jedis的ShardedJedisPool来管理,我们定义该配置文件为:spring-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:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-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/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/util
    http://www.springframework.org/schema/util/spring-util-3.2.xsd">
 
  <!-- 引入jedis配置文件 -->
    <context:property-placeholder location="classpath:conf/properties/redis.properties"
    ignore-unresolvable="true" />
   
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal">
        <value>${redis.pool.maxActive}</value>
        </property>
        <property name="maxIdle">
         <value>${redis.pool.maxIdle}</value>
        </property>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
    </bean>
   
     <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool"  scope="singleton">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1">
            <list>
                <bean class="redis.clients.jedis.JedisShardInfo">
                    <constructor-arg name="host" value="${redis.uri}" />
                </bean>
            </list>
        </constructor-arg>
    </bean>
</beans>

几个注意的点:

(1)如果你有多个数据源需要通过<context:property-placeholder管理,且不愿意放在一个配置文件里,那么一定要加上ignore-unresolvable=“true"

(2)注意新版的(具体从哪个版本开始不清楚,有兴趣可以查一下)JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码。

(3)ShardedJedisPool有多种构造函数,选择你需要的(具体看源码),示例中只初始化了一个分片,并使用了通过指定host的构造器(具体格式见下文),如果有集群,在<list>下增加新的<bean>即可。

2、准备redis.properties,内容如下:

redis.pool.maxActive=200
redis.pool.maxIdle=50
redis.pool.minIdle=10
redis.pool.maxWaitMillis=20000
redis.pool.maxWait=300
redis.uri = redis://[email protected]:6379/0
redis.timeout=30000

这里要注意redis.uri的格式:redis://[密码]@[服务器地址]:[端口]/[db index]

建议大家使用这种方式,配置内容少,还能自定义db index,非常适合开发、测试和线上环境的切换

3、将spring-redis.xml加入web.xml的context中,如下:

<context-param>
    <param-name>contextConfigLocation</param-name>

<param-value>classpath:conf/spring-redis.xml</param-value>

</context-param>

如果你有多个数据源通过spring管理(如mysql),则同时加载,如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:conf/spring-mybatis.xml,classpath:conf/spring-redis.xml</param-value>

</context-param>

3、以上所有的配置已完成,接下来的代码的实现

(1)推荐大家使用统一的类来管理Jedis实例的生成和回收,参考代码如下:JedisDataSourceImpl.class

@Repository("jedisDS")
public class JedisDataSourceImpl implements JedisDataSource {
    private static final Logger LOG = LoggerFactory.getLogger(JedisDataSourceImpl.class);
    
    @Autowired
    private ShardedJedisPool shardedJedisPool;
    
    @Override
    public ShardedJedis getRedisClient() {
        ShardedJedis shardJedis = null;
        try {
            shardJedis = shardedJedisPool.getResource();
            return shardJedis;
        } catch (Exception e) {
            LOG.error("[JedisDS] getRedisClent error:" + e.getMessage());
            if (null != shardJedis)
                shardJedis.close();
        }
        return null;
    }

    @Override
    public void returnResource(ShardedJedis shardedJedis) {
        shardedJedis.close();
    }

    @Override
    public void returnResource(ShardedJedis shardedJedis, boolean broken) {
        shardedJedis.close();
    }

}

这里要注意的是Jedis实例的回收,从jedis2.6开始,原returnResource方式已经提示在后续版本中不再支持,所以不建议大家再用ShardedJedisPool里的returnResource和retureBrokenResource方法,虽然在2.7中还支持(毕竟是因为这两个方法存在漏洞)。

(2)编写具体的Jedis操作类(片断):RedisClientTemplate.class

@Repository("redisClientTemplate")
public class RedisClientTemplate {
    private static final Logger log = LoggerFactory.getLogger(RedisClientTemplate.class);

    @Autowired
    private JedisDataSource redisDataSource;

    public void disconnect() {
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        shardedJedis.disconnect();
    }

    /**
     * 设置单个值
     * 
     * @param key
     * @param value
     * @return
     */
    public String set(String key, String value) {
        String result = null;

        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.set(key, value);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    /**
     * 获取单个值
     * 
     * @param key
     * @return
     */
    public String get(String key) {
        String result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }

        boolean broken = false;
        try {
            result = shardedJedis.get(key);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public Boolean exists(String key) {
        Boolean result = false;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.exists(key);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public String type(String key) {
        String result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.type(key);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    /**
     * 在某段时间后失效
     * 
     * @param key
     * @param seconds
     * @return
     */
    public Long expire(String key, int seconds) {
        Long result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.expire(key, seconds);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    /**
     * 在某个时间点失效
     * 
     * @param key
     * @param unixTime
     * @return
     */
    public Long expireAt(String key, long unixTime) {
        Long result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.expireAt(key, unixTime);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public Long ttl(String key) {
        Long result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.ttl(key);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public boolean setbit(String key, long offset, boolean value) {

        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        boolean result = false;
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.setbit(key, offset, value);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public boolean getbit(String key, long offset) {
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        boolean result = false;
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;

        try {
            result = shardedJedis.getbit(key, offset);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public long setRange(String key, long offset, String value) {
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        long result = 0;
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.setrange(key, offset, value);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    public String getRange(String key, long startOffset, long endOffset) {
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        String result = null;
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.getrange(key, startOffset, endOffset);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }
}

(3)好了,接下来在你的业务代码里加载RedisClientTemplate.class就可以了。

时间: 2024-10-10 07:05:05

使用Spring + Jedis集成Redis的相关文章

Spring + Jedis集成Redis

这几天没事,就把之前学习的redis代码整理一遍,废话不多说,上步骤. 1.pom.xml引入资源: <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.0.RELEASE</version> </dependency> <depen

Spring Boot 2.X(六):Spring Boot 集成 Redis

Redis 简介 什么是 Redis Redis 是目前使用的非常广泛的免费开源内存数据库,是一个高性能的 key-value 数据库. Redis 与其他 key-value 缓存(如 Memcached )相比有以下三个特点: 1.Redis 支持数据的持久化,它可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用. 2.Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储. 3.Redis 支持数据的备份

Spring Cache集成redis

Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set –有序集合)和hash(哈希类型).这些数据类型都支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据

【spring boot】【redis】spring boot 集成redis的发布订阅机制

一.简单介绍 1.redis的发布订阅功能,很简单. 消息发布者和消息订阅者互相不认得,也不关心对方有谁. 消息发布者,将消息发送给频道(channel). 然后是由 频道(channel)将消息发送给对自己感兴趣的 消息订阅者们,进行消费. 2.redis的发布订阅和专业的MQ相比较 1>redis的发布订阅只是最基本的功能,不支持持久化,消息发布者将消息发送给频道.如果没有订阅者消费,消息就丢失了. 2>在消息发布过程中,如果客户端和服务器连接超时,MQ会有重试机制,事务回滚等.但是Red

spring boot 集成 Redis

前提:你已经安装了Redis 1.创建一个spring boot 工程 2.pom 引入依赖:spring-boot-starter-data-redis <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 3.在application

spring boot 集成 redis lettuce(jedis)

spring boot框架中已经集成了redis,在1.x.x的版本时默认使用的jedis客户端,现在是2.x.x版本默认使用的lettuce客户端 引入依赖 <!-- spring boot redis 缓存引入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactI

Spring Boot (24) 使用Spring Cache集成Redis

Spring 3.1引入了基于注解(annotation)的缓存(cache)技术,它本质不是一个具体的缓存实现方案,而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的个助攻annotation,就能够达到缓存方法的返回对象的效果. 特点 具备相当好的灵活性,不仅能够使用SpEL来定义缓存的key和各种condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如EHCache.Redis.Guava的集成. 基于annotation即可使得现有代码支持缓存 开箱即用O

spring boot2 集成Redis

1. 引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository -->

Spring boot集成Redis(2)—RedisTemplate的使用来存储Map集合

前言:上一篇文章我们用的是StringRedisTemplate,但是它存在一点问题,也迫使我重新写了代码,问题是:在我们往缓存中存入数字形式的String类型时,我们在利用Spring could将获取到的数据发送到另一服务时,我们发现数据已经被强转为Integer类型了,因为我们可能传输的数据庞大,类型多样,为了统一类型,以及开发方便,所以我将缓存改成RedisTemplate这种类型,进行增删改查的操作,文中没有特别举例更新操作,其更新操作与添加操作一样,当key一样时进行添加就会覆盖原v