Spring Cache集成Redis

redis大家都耳熟能详了,spring context默认没有实现redis的cache相关接口,我们需要自己实现,并借助org.springframework.cache.support.SimpleCacheManager进行redis缓存管理。

添加jar包:

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.5.2</version>
  </dependency>cache接口实现:


package org.springframework.cache.demo.redis;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

public class RedisCache implements Cache {

 private RedisTemplate<String, Object> redisTemplate;
 private String name;

 public RedisTemplate<String, Object> getRedisTemplate() {
  return redisTemplate;
 }

 public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
  this.redisTemplate = redisTemplate;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public String getName() {
  return this.name;
 }

 @Override
 public Object getNativeCache() {
  return this.redisTemplate;
 }

 @Override
 public ValueWrapper get(Object key) {
  final String keyf = (String) key;
  Object object = null;
  object = redisTemplate.execute(new RedisCallback<Object>() {
   public Object doInRedis(RedisConnection connection) throws DataAccessException {

    byte[] key = keyf.getBytes();
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    return toObject(value);
   }
  });
  return (object != null ? new SimpleValueWrapper(object) : null);
 }

 @Override
 public void put(Object key, Object value) {
  final String keyf = (String) key;
  final Object valuef = value;
  final long liveTime = 86400;

  redisTemplate.execute(new RedisCallback<Long>() {
   public Long doInRedis(RedisConnection connection) throws DataAccessException {
    byte[] keyb = keyf.getBytes();
    byte[] valueb = toByteArray(valuef);
    connection.set(keyb, valueb);
    if (liveTime > 0) {
     connection.expire(keyb, liveTime);
    }
    return 1L;
   }
  });
 }

 /**
  * 描述 : <Object转byte[]>. <br>
  * <p>
  * <使用方法说明>
  * </p>
  *
  * @param obj
  * @return
  */
 private byte[] toByteArray(Object obj) {
  byte[] bytes = null;
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  try {
   ObjectOutputStream oos = new ObjectOutputStream(bos);
   oos.writeObject(obj);
   oos.flush();
   bytes = bos.toByteArray();
   oos.close();
   bos.close();
  } catch (IOException ex) {
   ex.printStackTrace();
  }
  return bytes;
 }

 /**
  * 描述 : <byte[]转Object>. <br>
  * <p>
  * <使用方法说明>
  * </p>
  *
  * @param bytes
  * @return
  */
 private Object toObject(byte[] bytes) {
  Object obj = null;
  try {
   ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
   ObjectInputStream ois = new ObjectInputStream(bis);
   obj = ois.readObject();
   ois.close();
   bis.close();
  } catch (IOException ex) {
   ex.printStackTrace();
  } catch (ClassNotFoundException ex) {
   ex.printStackTrace();
  }
  return obj;
 }

 @Override
 public void evict(Object key) {
  final String keyf = (String) key;
  redisTemplate.execute(new RedisCallback<Long>() {
   public Long doInRedis(RedisConnection connection) throws DataAccessException {
    return connection.del(keyf.getBytes());
   }
  });
 }

 @Override
 public void clear() {
  redisTemplate.execute(new RedisCallback<String>() {
   public String doInRedis(RedisConnection connection) throws DataAccessException {
    connection.flushDb();
    return "ok";
   }
  });
 }

 @SuppressWarnings("unchecked")
 @Override
 public <T> T get(Object key, Class<T> type) {
  final String keyf = (String) key;
  Object object = null;
  object = redisTemplate.execute(new RedisCallback<Object>() {
   public Object doInRedis(RedisConnection connection) throws DataAccessException {

    byte[] key = keyf.getBytes();
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    return toObject(value);
   }
  });
  return (T) object;
 }

 @Override
 public ValueWrapper putIfAbsent(Object key, Object value) {
  put(key, value);
  return new SimpleValueWrapper(value);
 }
}
spring配置:


<?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:cache="http://www.springframework.org/schema/cache"
 xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">

 <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
 <cache:annotation-driven cache-manager="cacheManager"/>

 <bean id="userService" class="org.springframework.cache.demo.UserService" />
 
    <!-- spring自己的换管理器,这里定义了两个缓存位置名称 ,既注解中的value --> 
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> 
        <property name="caches"> 
            <set> 
                <bean class="org.springframework.cache.demo.redis.RedisCache"> 
                    <property name="redisTemplate" ref="redisTemplate" /> 
                    <property name="name" value="userCache"/> 
                </bean> 
            </set> 
        </property> 
    </bean>
   
    <!-- redis 相关配置 --> 
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> 
        <property name="maxIdle" value="300" />       
        <property name="maxWaitMillis" value="3000" /> 
        <property name="testOnBorrow" value="true" /> 
    </bean> 
    <bean id="connectionFactory" 
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
        p:host-name="192.168.1.90" p:port="6379" p:pool-config-ref="poolConfig" 
        p:database="0" />
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> 
        <property name="connectionFactory" ref="connectionFactory" /> 
    </bean> 
</beans>
除了以上方式,在spring-data项目中增加了对redis的支持spring-data-redis,单独引入依赖:


<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-redis</artifactId>
   <version>1.4.2.RELEASE</version>
  </dependency>使用spring-data-redis提供的RedisTemplate对redis操作,spring配置如下:


<?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:context='http://www.springframework.org/schema/context'
 xmlns:c='http://www.springframework.org/schema/c'
 xmlns:p='http://www.springframework.org/schema/p'
 xmlns:cache='http://www.springframework.org/schema/cache'
 xsi:schemaLocation='
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
        '>

 <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
 <cache:annotation-driven cache-manager="cacheManager" />

 <bean id="userService" class="org.springframework.cache.demo.UserService" />

 <!-- 声明cacheManager -->
 <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"
  c:template-ref="redisTemplate" />

 <!-- redis 相关配置 -->
 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  <property name="maxIdle" value="300" />
  <property name="maxWaitMillis" value="3000" />
  <property name="testOnBorrow" value="true" />
 </bean>
 <bean id="jedisConnectionFactory"
  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
  p:host-name="192.168.1.90" p:port="6379" p:pool-config-ref="jedisPoolConfig"
  p:database="0" p:use-pool="true" />

 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
  p:connection-factory-ref="jedisConnectionFactory" />
</beans>

下面关于Redis的文章您也可能喜欢,不妨参考下:

Redis 的详细介绍:请点这里
Redis 的下载地址:请点这里

相关推荐