spring配置redis注解缓存

  前几天在spring整合Redis的时候使用了手动的方式,也就是可以手动的向redis添加缓存与清除缓存,参考:http://www.cnblogs.com/qlqwjy/p/8562703.html

  今天想的将spring注解整合Redis缓存弄明白,于是通过查阅资料,先做记录如下:

大致步骤如下:

    0.spring的主配置中声明注解缓存:<cache:annotation-driven cache-manager="redisCacheManager"/>

      1.maven的pom.xml文件导入架包

   2.配置文件添加配置

   3.spring管理bean的生成,xml文件配置

   4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则

   5.在你想要做缓存的地方,使用注解进行缓存

  • 0.spring的主配置中声明注解缓存:<cache:annotation-driven cache-manager="redisCacheManager"/>

  注意:此步骤必须做,必须声明采用的缓存管理器是自己配置的redisCacheManager,否则会报错。

<cache:annotation-driven cache-manager="redisCacheManager"/>
  • 1.maven的pom.xml文件导入架包

注意:

  引入jackson是为了手动添加缓存

        <!-- jedis依赖 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.8.4.RELEASE</version>
        </dependency>
        <!-- jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.1.0</version>
        </dependency>
  • 2.配置文件添加配置redis.properties
#访问地址  
redis.host=127.0.0.1  
#访问端口  
redis.port=6379  
#注意,如果没有password,此处不设置值,但这一项要保留  
redis.password=  
  
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。  
redis.maxIdle=300  
#连接池的最大数据库连接数。设为0表示无限制  
redis.maxActive=600  
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。  
redis.maxWait=1000  
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;  
redis.testOnBorrow=true
  • 3.spring管理bean的生成,xml文件配置   applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">

    <!-- 连接池基本参数配置,类似数据库连接池 -->
    <context:property-placeholder location="classpath:redis.properties"
        ignore-unresolvable="true" />
    
    <!-- redis连接池 -->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <!-- 连接池配置,类似数据库连接池 -->
    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}"></property>
        <property name="port" value="${redis.port}"></property>
        <!-- <property name="password" value="${redis.pass}"></property> -->
        <property name="poolConfig" ref="poolConfig"></property>
    </bean>

    <!--redis操作模版,使用该对象可以操作redis  -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >    
        <property name="connectionFactory" ref="jedisConnectionFactory" />    
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->    
        <property name="keySerializer" >    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />    
        </property>    
        <property name="valueSerializer" >    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />    
        </property>    
        <property name="hashKeySerializer">    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
        </property>    
        <property name="hashValueSerializer">    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>    
        </property>    
        <!--开启事务  -->  
        <property name="enableTransactionSupport" value="true"></property>  
    </bean >   


      <!-- 配置RedisCacheManager -->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
        <property name="defaultExpiration" value="${redis.expiration}" />
    </bean>

    <!-- 配置RedisCacheConfig -->
    <bean id="redisCacheConfig" class="cn.qlq.util.RedisCacheConfig">
        <constructor-arg ref="jedisConnectionFactory"/>
        <constructor-arg ref="redisTemplate"/>
        <constructor-arg ref="redisCacheManager"/>
    </bean>

    <!-- 下面这个是整合Mybatis的二级缓存使用的 -->
    <bean id="redisCacheTransfer" class="cn.qlq.jedis.RedisCacheTransfer">
        <property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
    </bean>

</beans>

JedisPoolConfig           jedis连接池配置对象

JedisConnectionFactory         jedis连接工厂,生成连接对象

RedisTemplate          RedisTemplate 对 RedisConnection 进行了封装。提供连接管理,序列化等功能,它对 Redis 的交互进行了更高层次的抽象,极大的方便和简化了 Redis 的操作

RedisCacheManager        做为 redis 统一的调度和管理者

RedisCacheConfig         RedisCacheConfig extends org.springframework.cache.annotation.CachingConfigurerSupport,自定义redis的key生成规则,如果不在注解参数中注明key=“”的话,就采用这个类中的key生成规则生成key

  • 4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则

      采用Java配置的方式注入到spring

package cn.qlq.util;

import java.lang.reflect.Method;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
    private volatile JedisConnectionFactory jedisConnectionFactory;
    private volatile RedisTemplate<String, String> redisTemplate;
    private volatile RedisCacheManager redisCacheManager;

    public RedisCacheConfig() {
        super();
    }

    /**
     * 带参数的构造方法 初始化所有的成员变量
     * 
     * @param jedisConnectionFactory
     * @param redisTemplate
     * @param redisCacheManager
     */
    public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate,
            RedisCacheManager redisCacheManager) {
        this.jedisConnectionFactory = jedisConnectionFactory;
        this.redisTemplate = redisTemplate;
        this.redisCacheManager = redisCacheManager;
    }

    public JedisConnectionFactory getJedisConnecionFactory() {
        return jedisConnectionFactory;
    }

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

    public RedisCacheManager getRedisCacheManager() {
        return redisCacheManager;
    }

    @Bean
    public KeyGenerator keyGenerator() {
      return new KeyGenerator() {
        @Override
        public Object generate(Object o, Method method, Object... params) {
          StringBuilder sb = new StringBuilder();
          sb.append(o.getClass().getName());
          sb.append(method.getName());
          for (Object param : params) {
            sb.append(param.toString());
          }
          return sb.toString();
        }
      };
    }
}

上面的自定义的key规则是类      本类名+方法名+参数名(中间没有逗号区分),例如:

Array2List.TestClassAndMethodAndParamfun1{2=ssssssssssssssssss, 1=ssssssssssssssssss}

  

所以我们可以对上面的自定义规则进行改造,将方法名和参数名进行隔开之后进行区分:(修改过的key的生成规则)
    public Object generate(Object o, Method method, Object... params) {
        //规定  本类名+方法名+参数名 为key
        StringBuilder sb = new StringBuilder();
        sb.append(o.getClass().getName());
        sb.append("-");
        sb.append(method.getName());
        sb.append("-");
        for (Object param : params) {
            sb.append(param.toString());
        }
        return sb.toString();
    }

结果:

Array2List.TestClassAndMethodAndParam-fun1-{2=ssssssssssssssssss, 1=ssssssssssssssssss}

  • 5.在你想要做缓存的地方,使用注解进行缓存

先介绍几个注解

  1》@CacheConfig  配置在类上,cacheNames即定义了本类中所有用到缓存的地方,都去找这个库。只要使用了这个注解,在方法上@Cacheable    @CachePut   @CacheEvict就可以不用写value去找具体库名了。【一般不怎么用】

  2》@Cacheable  配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果,下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找

  3》@CachePut   类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果

  4》@CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)

例子:

最直观的表现:首次登录,会有一条数据库的查询语句在控制台。

       退出再登录,不会执行数据库的查询,直接从数据库中取出缓存,登录成功。

说明:

  ①使用了@Cacheable(value="myUser"),即表示缓存中有,直接从缓存取出,没有的话先从数据库中查出,然后再插入

  ②如果未在类上使用@CacheConfig注解规定数据要缓存到哪个库中,就必须给value一个值,规定数据最后缓存到哪个redis库中

  ③因为redis缓存数据实际就是键值对的形式存储,因此必须给定key-value的key,这里没有给key参数赋值,所以key的生成规则按照上面工具类中规定的key生成的

  ④key-value的value就是本方法的返回值,如果要缓存登录用户信息,本方法需要进行修改,返回user对象就可以缓存到key-value的value中

例如:

Action:

package cn.qlq.Action;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.Validate;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.github.pagehelper.PageHelper;
import com.opensymphony.xwork2.ActionSupport;

import cn.qlq.bean.User;
import cn.qlq.service.UserService;

@Controller
@Scope("prototype")
@SuppressWarnings("all")
public class UserAction extends ActionSupport {
    private Map<String, Object> response;
    @Autowired
    private UserService userService;
    private int id;
    private String name;

    /**
     * 测试清除注解保存的缓存的同时手动添加单个缓存
     * 
     * @return
     */
    public String add() {
        try {
            userService.addUser(id, name);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "add";
    }

    /**
     * 测试查询单个的时候注解添加单个缓存
     * 
     * @return
     * @throws Exception
     */
    public String find() throws Exception {
        User user = userService.findUserById(id);
        HttpServletRequest request = ServletActionContext.getRequest();
        request.setAttribute("user", user);
        return "find";
    }

    
    /**
     * 测试删除单个的时候注解删除单个缓存
     * @return
     */
    public String delete() {
        try {
            userService.deleteById(id);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "delete";
    }
    
    /**
     * 测试注解缓存,将查出来的集合结果加入缓存
     * 
     * @return
     * @throws Exception
     */
    public String findPage() throws Exception {
        response = new HashMap();
        if (name == null)
            name = "111";
        // 第三个参数代表排序方式
        PageHelper.startPage(2, 2, "id desc");
        List<User> users = userService.findUsersByPage(name);
        response.put("users", users);
        return "success";
    }

    public Map getResponse() {
        return response;
    }

    public void setResponse(Map response) {
        this.response = response;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

}

 Service添加缓存与删除缓存:

package cn.qlq.service.impl;

import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import cn.qlq.bean.User;
import cn.qlq.mapper.UserMapper;
import cn.qlq.service.UserService;
import cn.qlq.util.RedisUtil;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserMapper userMapper;
    
    
    //查询出来的时候添加单个缓存
    @Cacheable(value="user",key="'user'+#id.toString()")
    @Override
    public User findUserById(int id) throws Exception {
        System.out.println("打印语句则没有走缓存");
        return userMapper.findUserById(id);
    }
    
    //删除数据库的时候删除redis的缓存
    @Override
    @CacheEvict(value="user",key="'user'+#id.toString()")
    public boolean deleteById(int id){
        return true;
    }
    
    
    //添加缓存
    @Cacheable(value="Alluser")
    @Override
    public List<User> findUsersByPage(String name) throws SQLException {
        System.out.println("打印语句则没有走缓存");
        return userMapper.findUsersByPage();
    }
    
    //清除上面的缓存,同时手动的添加一个缓存看能否实现
    @CacheEvict(value="Alluser")
    @Override
    public int addUser(int id, String name) throws SQLException {
        redisUtil.set("mykey", "myvalue");
        return userMapper.addUser(id, name);
    }

}

解释:

  findUserById()函数将单个用户存入缓存中,例如访问:http://localhost/SSM/user_find?id=1  后查看redis:

    函数注解上面的user加上~value作为一个zset存入缓存,值为具体的缓存的键:

      

    

  继续访问 http://localhost/SSM/user_find?id=2   http://localhost/SSM/user_find?id=3   http://localhost/SSM/user_find?id=4之后

  继续访问http://localhost/SSM/user_delete?id=4  删除一个user4缓存:

总结:

    此版本的redisspring-data-redis在设置缓存的时候是将value的值加上~keys存为一个zset,值就是每个具体的缓存的key。例如上面

@Cacheable(value="user",key="'user'+#id.toString()")

    就是将user~keys作为一个zset,然后其值为user1.......(缓存的键)

   

     删除缓存的时候删除指定的键,然后从指定的value加上~keys的zset中删除对应的值,完成删除一个缓存。

             如果删除的时候只指定了其value,而没有指定key值,则跟据value值加上~keys作为key找到对应的zset,根据zset值获取所有的key后删除,然后删除此zset即完成删除。

最后给出这几个注解的具体参数以及使用相关配图参考。

表 1. @Cacheable 作用和配置方法

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 主要的参数
value 缓存的名称,缓存中具体哪个数据库,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,或者方法参数列表中的任意一个参数,或者字符串+参数组合

例如:
@Cacheable(value=”testcache”,key=”#userName”)

@Cacheable(value=”testcache”,key=” '字符串'+#userName”)

condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
 
表 2. @CachePut 作用和配置方法
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
 
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

*************************************************************************************************************************************************************************************

*************************************************************************************************************************************************************************************

spEL表达式的使用方法:http://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/expressions.html

关于注解实现Redis缓存的方法,只有将key设计的合理且强大,整个的缓存在项目中才能通用且高效。否则,就像我上面的简单的例子一样,真的是搞笑了。

总结:

  在redis做缓存的时候最好是每个缓存的生命周期不固定,也就是分散的使缓存失效。可以设置有效期为3-9小时。具体的做法就是在Java中产生一个3-9小时的随机数。

注意:

  在IDEA中整合的时候发现用注解配置Bean报错,因此将上面的KeyGenerator单独抽成类,注入到Spring中并在cache标签中指明key生成器:

KeyGenerator.java
package cn.xm.jwxt.utils;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author: qlq
 * @Description
 * @Date: 22:49 2018/3/25
 */
public class KeyGenerator implements org.springframework.cache.interceptor.KeyGenerator {
    @Override
    public Object generate(Object o, Method method, Object... params) {
        //规定  本类名+方法名+参数名 为key
        StringBuilder sb = new StringBuilder();
        sb.append(o.getClass().getName());
        sb.append(method.getName());
        for (Object param : params) {
            sb.append(param.toString());
        }
        return sb.toString();
    }
}

key的生成规则也可以修改为:

    public Object generate(Object o, Method method, Object... params) {
        //规定  本类名+方法名+参数名 为key
        StringBuilder sb = new StringBuilder();
        sb.append(o.getClass().getName());
        sb.append("-");
        sb.append(method.getName());
        sb.append("-");
        for (Object param : params) {
            sb.append(param.toString());
        }
        return sb.toString();
    }
RedisCacheConfig.java
package cn.xm.jwxt.utils;

import java.lang.reflect.Method;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
/**
 * 注解redis缓存集成spring需要使用的配置类  java配置的方式注入bean到spring
 * @author liqiang
 *
 */
public class RedisCacheConfig extends CachingConfigurerSupport {
    private volatile JedisConnectionFactory jedisConnectionFactory;
    private volatile RedisTemplate<String, String> redisTemplate;
    private volatile RedisCacheManager redisCacheManager;

    public RedisCacheConfig() {
        super();
    }

    /**
     * 带参数的构造方法 初始化所有的成员变量
     * 
     * @param jedisConnectionFactory
     * @param redisTemplate
     * @param redisCacheManager
     */
    public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate,
            RedisCacheManager redisCacheManager) {
        this.jedisConnectionFactory = jedisConnectionFactory;
        this.redisTemplate = redisTemplate;
        this.redisCacheManager = redisCacheManager;
    }

    public JedisConnectionFactory getJedisConnecionFactory() {
        return jedisConnectionFactory;
    }

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

    public RedisCacheManager getRedisCacheManager() {
        return redisCacheManager;
    }
}

applicationContext-redis.xml

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

    <cache:annotation-driven cache-manager="redisCacheManager" key-generator="keyGenerator"/>

    <!-- 连接池基本参数配置,类似数据库连接池 -->
    <context:property-placeholder location="classpath:redis.properties"
        ignore-unresolvable="true" />
    
    <!-- redis连接池 -->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <!-- 连接池配置,类似数据库连接池 -->
    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}"></property>
        <property name="port" value="${redis.port}"></property>
        <!-- <property name="password" value="${redis.pass}"></property> -->
        <property name="poolConfig" ref="poolConfig"></property>
    </bean>

    <!--redis操作模版,使用该对象可以操作redis  -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >    
        <property name="connectionFactory" ref="jedisConnectionFactory" />    
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->    
        <property name="keySerializer" >    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />    
        </property>    
        <property name="valueSerializer" >    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />    
        </property>    
        <property name="hashKeySerializer">    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
        </property>    
        <property name="hashValueSerializer">    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>    
        </property>    
        <!--开启事务  -->  
        <property name="enableTransactionSupport" value="true"></property>  
    </bean >


    <!-- 配置RedisCacheManager -->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
        <property name="defaultExpiration" value="${redis.expiration}" />
    </bean>

    <!-- 配置RedisCacheConfig -->
    <bean id="redisCacheConfig" class="cn.xm.jwxt.utils.RedisCacheConfig">
        <constructor-arg ref="jedisConnectionFactory"/>
        <constructor-arg ref="redisTemplate"/>
        <constructor-arg ref="redisCacheManager"/>
    </bean>

    <!---->
    <bean id="keyGenerator" class="cn.xm.jwxt.utils.KeyGenerator"></bean>

    <!-- 下面这个是整合Mybatis的二级缓存使用的 -->
<!--    <bean id="redisCacheTransfer" class="cn.qlq.jedis.RedisCacheTransfer">
        <property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
    </bean>-->

</beans>

 参考:https://www.cnblogs.com/sxdcgaq8080/p/7228163.html

手动redis注解集成spring:http://www.cnblogs.com/qlqwjy/p/8562703.html

关于缓存注解的更详细的使用方法参考:http://www.cnblogs.com/qlqwjy/p/8559119.html 

原文地址:https://www.cnblogs.com/qlqwjy/p/8574121.html