基于Spring注解@cacheable 集成redis

时间:2021-04-06 20:36:09
1、集成的话,对版本要求也是非常重要的。这里采用的是spring4.2版本。spring4在后采用的是jackson转化器,在这点要注意一下
首先在pom.xml中引入相关jar包。
(1):引入spring 和jackson包
<project xmlns=" http://maven.apache.org/POM/4.0.0" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://maven.apache.org/POM/4.0.0  http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.daqsoft</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>server Maven Webapp</name>
<url> http://maven.apache.org</url>
<properties>
<java.version>1.8</java.version>
 <!-- spring版本号 -->  
    <spring.version>4.2.0.RELEASE</spring.version>  
    <!-- mybatis版本号 -->  
    <mybatis.version>3.2.6</mybatis.version>  
    <!-- log4j日志文件管理包版本 -->  
    <slf4j.version>1.7.7</slf4j.version>  
    <log4j.version>1.2.17</log4j.version>
     <hibernate.version>4.3.8.Final</hibernate.version>  
</properties>
<dependencies>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>

    <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-core</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-web</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-oxm</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-tx</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-jdbc</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-webmvc</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-aop</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-context-support</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  

     <dependency>  
         <groupId>org.springframework</groupId>  
         <artifactId>spring-test</artifactId>  
         <version>${spring.version}</version>  
     </dependency>  
     
     <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.4.RELEASE</version>
  </dependency>

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.0</version>
     </dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.7</version>
</dependency>
(2):引入redis相关jar包
            <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.6.0.RELEASE</version>
    </dependency>
   
    <dependency>  
        <groupId>redis.clients</groupId>  
        <artifactId>jedis</artifactId>  
        <version>2.7.3</version>  
    </dependency>
 
2、编写redis配置文件
redis.host=127.0.0.1       #绑定的主机地址
redis.port=6379             #指定Redis监听端口,默认端口为6379
redis.pass=
redis.maxIdle=10         #最大空闲数:空闲链接数大于maxIdle时,将进行回收
redis.maxActive=600  #最大连接数:能够同时建立的“最大链接个数”
redis.maxWait=1000    #最大等待时间:单位ms
redis.timeout=100000  #当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
redis.testOnBorrow=true  #使用连接时,检测连接是否成功
redis.dbIndex=0    #代表存储是从第0个开始
 
2、编写spring主配置文件。此出只写集成的部分
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
   <list>
    <value>/WEB-INF/jdbc.properties</value>
    <value>/WEB-INF/redis.properties</value>   //引入redis配置文件
   </list>
  </property>
 </bean>
 
//redis主配置信息
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
        <property name="maxIdle" value="${redis.maxIdle}" />  
        <property name="maxTotal" value="${redis.maxActive}" />  
        <property name="maxWaitMillis" value="${redis.maxWait}" />  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
    </bean>  
  <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
         <property name="usePool" value="true"></property>  
        <property name="hostName" value="${redis.host}" />  
        <property name="port" value="${redis.port}" />  
        <property name="password" value="${redis.pass}" />  
        <property name="timeout" value="${redis.timeout}" />  
        <property name="database" value="${redis.dbIndex}"></property>
        <constructor-arg index="0" ref="poolConfig" />  
        </bean>    
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
        <property name="connectionFactory"   ref="connectionFactory" />  
    </bean>
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">    
         <property name="caches">    
            <set>    
                <bean class="com.cuit.utils.RedisCache">     //注入RedisCache    bean可以配置多个。指定不同的value
                     <property name="redisTemplate" ref="redisTemplate" />    
                     <property name="name" value="common"/>     //此处定义的common。必须和注解中的value对应
                </bean>  
            </set>    
         </property>    
     </bean> 
 
编写redis   RedisCache类
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() {  
        // TODO Auto-generated method stub    
         return this.name;    
     }  
   
     @Override    
     public Object getNativeCache() {  
       // TODO Auto-generated method stub    
         return this.redisTemplate;    
     }  
   
     @Override    
     public ValueWrapper get(Object key) {  
       // TODO Auto-generated method stub  
       System.out.println("读取缓存");  
       final String keyf =  key.toString();  
       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) {  
        // TODO Auto-generated method stub  
        System.out.println("插入缓存");  
        final String keyf = key.toString();    
        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;    
              }    
          });    
       }  
   
       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;    
         }    
   
        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) {    
          // TODO Auto-generated method stub    
          System.out.println("del key");  
          final String keyf = key.toString();    
          redisTemplate.execute(new RedisCallback<Long>() {    
          public Long doInRedis(RedisConnection connection)    
                    throws DataAccessException {    
              return connection.del(keyf.getBytes());    
             }    
           });    
         }  
   
         @Override    
         public void clear() {    
            // TODO Auto-generated method stub    
             System.out.println("clear key");  
            redisTemplate.execute(new RedisCallback<String>() {    
                 public String doInRedis(RedisConnection connection)    
                         throws DataAccessException {    
                   connection.flushDb();    
                     return "ok";    
                }    
            });    
         }  
   
         @Override  
         public <T> T get(Object key, Class<T> type) {  
             // TODO Auto-generated method stub  
             return null;  
         }  
       
         @Override  
         public ValueWrapper putIfAbsent(Object key, Object value) {  
             // TODO Auto-generated method stub  
             return null;  
         }  
         
 } 
 
 
 
3、开始测试。建议写在各自实体的实现类
基于Spring注解@cacheable 集成redis
 
4、结果
 
第一次的时候读取,走的db。然后插入缓存
基于Spring注解@cacheable 集成redis
基于Spring注解@cacheable 集成redis
第二次就直接走的缓存
基于Spring注解@cacheable 集成redis
 
基于Spring注解@cacheable 集成redis
  基于Spring注解@cacheable 集成redis
redis
基于Spring注解@cacheable 集成redis
 
附:key的生成参考
Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。

属性名称

描述

示例

methodName

当前方法名

#root.methodName

method

当前方法

#root.method.name

target

当前被调用的对象

#root.target

targetClass

当前被调用的对象的class

#root.targetClass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的Cache

#root.caches[0].name