zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    雅虎公司C#笔试题
    DES
    从Socket看Visual C#.Net网络程序开发
    进一步接触C#委托与事件
    学习C#消息:循序渐进
    解惑答疑:C#委托和事件
    利用Visual C#实现Windows管道技术1
    使用命名管道通过网络在进程之间进行通信
    C#体验编程技术 类与对象
    学习C#实现HTTP协议:多线程文件传输
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/8574121.html
Copyright © 2011-2022 走看看