spring整合redis緩存,以註解(@Cacheable、@CachePut、@CacheEvict)形式使用

maven項目中在pom.xml中依賴2個jar包,其他的spring的jar包省略:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. <dependency>  
  2.    <groupId>redis.clients</groupId>  
  3.    <artifactId>jedis</artifactId>  
  4.    <version>2.8.1</version>  
  5. </dependency>  
  6. <dependency>  
  7.    <groupId>org.springframework.data</groupId>  
  8.    <artifactId>spring-data-redis</artifactId>  
  9.    <version>1.7.2.RELEASE</version>  
  10. </dependency>  


spring-Redis.xml中的內容:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"    
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  6.     xmlns:cache="http://www.springframework.org/schema/cache"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans      
  8.                         http://www.springframework.org/schema/beans/spring-beans-4.2.xsd      
  9.                         http://www.springframework.org/schema/context      
  10.                         http://www.springframework.org/schema/context/spring-context-4.2.xsd      
  11.                         http://www.springframework.org/schema/mvc      
  12.                         http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd  
  13.                         http://www.springframework.org/schema/cache   
  14.                         http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">   
  15.       
  16.     <context:property-placeholder location="classpath:redis-config.properties" />    
  17.   
  18.     <!-- 啓用緩存註解功能,這個是必須的,否則註解不會生效,另外,該註解一定要聲明在spring主配置文件中才會生效 -->    
  19.     <cache:annotation-driven cache-manager="cacheManager" />    
  20.       
  21.      <!-- redis 相關配置 -->    
  22.      <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">    
  23.          <property name="maxIdle" value="${redis.maxIdle}" />     
  24.          <property name="maxWaitMillis" value="${redis.maxWait}" />    
  25.          <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
  26.      </bean>    
  27.   
  28.      <bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"    
  29.        p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>    
  30.     
  31.      <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">    
  32.          <property name="connectionFactory" ref="JedisConnectionFactory" />    
  33.      </bean>    
  34.       
  35.      <!-- spring自己的緩存管理器,這裏定義了緩存位置名稱 ,即註解中的value -->    
  36.      <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">    
  37.          <property name="caches">    
  38.             <set>    
  39.                 <!-- 這裏可以配置多個redis -->  
  40.                 <!-- <bean class="com.cn.util.RedisCache">    
  41.                      <property name="redisTemplate" ref="redisTemplate" />    
  42.                      <property name="name" value="default"/>    
  43.                 </bean> -->    
  44.                 <bean class="com.cn.util.RedisCache">    
  45.                      <property name="redisTemplate" ref="redisTemplate" />    
  46.                      <property name="name" value="common"/>    
  47.                      <!-- common名稱要在類或方法的註解中使用 -->  
  48.                 </bean>  
  49.             </set>    
  50.          </property>    
  51.      </bean>    
  52.       
  53. </beans>    


Redis-config.properties中的內容:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. # Redis settings  
  2. # server IP  
  3. redis.host=127.0.0.1  
  4. # server port  
  5. redis.port=6379  
  6. # server pass  
  7. redis.pass=  
  8. # use dbIndex  
  9. redis.database=0  
  10. # 控制一個pool最多有多少個狀態爲idle(空閒的)的jedis實例  
  11. redis.maxIdle=300  
  12. # 表示當borrow(引入)一個jedis實例時,最大的等待時間,如果超過等待時間(毫秒),則直接拋出JedisConnectionException;    
  13. redis.maxWait=3000  
  14. # 在borrow一個jedis實例時,是否提前進行validate操作;如果爲true,則得到的jedis實例均是可用的    
  15. redis.testOnBorrow=true  

com.cn.util.RedisCache類中的內容:

[java] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. package com.cn.util;  
  2.   
  3. import java.io.ByteArrayInputStream;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.ObjectInputStream;  
  7. import java.io.ObjectOutputStream;  
  8.   
  9. import org.springframework.cache.Cache;  
  10. import org.springframework.cache.support.SimpleValueWrapper;  
  11. import org.springframework.dao.DataAccessException;  
  12. import org.springframework.data.redis.connection.RedisConnection;  
  13. import org.springframework.data.redis.core.RedisCallback;  
  14. import org.springframework.data.redis.core.RedisTemplate;  
  15.   
  16. public class RedisCache implements Cache{  
  17.   
  18.     private RedisTemplate<String, Object> redisTemplate;    
  19.     private String name;    
  20.     public RedisTemplate<String, Object> getRedisTemplate() {  
  21.         return redisTemplate;    
  22.     }  
  23.        
  24.     public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {  
  25.         this.redisTemplate = redisTemplate;    
  26.     }  
  27.        
  28.     public void setName(String name) {  
  29.         this.name = name;    
  30.     }  
  31.        
  32.     @Override    
  33.     public String getName() {  
  34.        // TODO Auto-generated method stub    
  35.         return this.name;    
  36.     }  
  37.   
  38.     @Override    
  39.     public Object getNativeCache() {  
  40.       // TODO Auto-generated method stub    
  41.         return this.redisTemplate;    
  42.     }  
  43.    
  44.     @Override    
  45.     public ValueWrapper get(Object key) {  
  46.       // TODO Auto-generated method stub  
  47.       System.out.println("get key");  
  48.       final String keyf =  key.toString();  
  49.       Object object = null;  
  50.       object = redisTemplate.execute(new RedisCallback<Object>() {  
  51.       public Object doInRedis(RedisConnection connection)    
  52.                   throws DataAccessException {  
  53.           byte[] key = keyf.getBytes();  
  54.           byte[] value = connection.get(key);  
  55.           if (value == null) {  
  56.              return null;  
  57.             }  
  58.           return toObject(value);  
  59.           }  
  60.        });  
  61.         return (object != null ? new SimpleValueWrapper(object) : null);  
  62.       }  
  63.     
  64.      @Override    
  65.      public void put(Object key, Object value) {  
  66.        // TODO Auto-generated method stub  
  67.        System.out.println("put key");  
  68.        final String keyf = key.toString();    
  69.        final Object valuef = value;    
  70.        final long liveTime = 86400;    
  71.        redisTemplate.execute(new RedisCallback<Long>() {    
  72.            public Long doInRedis(RedisConnection connection)    
  73.                    throws DataAccessException {    
  74.                 byte[] keyb = keyf.getBytes();    
  75.                 byte[] valueb = toByteArray(valuef);    
  76.                 connection.set(keyb, valueb);    
  77.                 if (liveTime > 0) {    
  78.                     connection.expire(keyb, liveTime);    
  79.                  }    
  80.                 return 1L;    
  81.              }    
  82.          });    
  83.       }  
  84.   
  85.       private byte[] toByteArray(Object obj) {    
  86.          byte[] bytes = null;    
  87.          ByteArrayOutputStream bos = new ByteArrayOutputStream();    
  88.          try {    
  89.            ObjectOutputStream oos = new ObjectOutputStream(bos);    
  90.            oos.writeObject(obj);    
  91.            oos.flush();    
  92.            bytes = bos.toByteArray();    
  93.            oos.close();    
  94.            bos.close();    
  95.           }catch (IOException ex) {    
  96.                ex.printStackTrace();    
  97.           }    
  98.           return bytes;    
  99.         }    
  100.   
  101.        private Object toObject(byte[] bytes) {  
  102.          Object obj = null;    
  103.            try {  
  104.                ByteArrayInputStream bis = new ByteArrayInputStream(bytes);    
  105.                ObjectInputStream ois = new ObjectInputStream(bis);    
  106.                obj = ois.readObject();    
  107.                ois.close();    
  108.                bis.close();    
  109.            } catch (IOException ex) {    
  110.                ex.printStackTrace();    
  111.             } catch (ClassNotFoundException ex) {    
  112.                ex.printStackTrace();    
  113.             }    
  114.             return obj;    
  115.         }  
  116.     
  117.        @Override    
  118.        public void evict(Object key) {    
  119.          // TODO Auto-generated method stub    
  120.          System.out.println("del key");  
  121.          final String keyf = key.toString();    
  122.          redisTemplate.execute(new RedisCallback<Long>() {    
  123.          public Long doInRedis(RedisConnection connection)    
  124.                    throws DataAccessException {    
  125.              return connection.del(keyf.getBytes());    
  126.             }    
  127.           });    
  128.         }  
  129.    
  130.         @Override    
  131.         public void clear() {    
  132.            // TODO Auto-generated method stub    
  133.             System.out.println("clear key");  
  134.            redisTemplate.execute(new RedisCallback<String>() {    
  135.                 public String doInRedis(RedisConnection connection)    
  136.                         throws DataAccessException {    
  137.                   connection.flushDb();    
  138.                     return "ok";    
  139.                }    
  140.            });    
  141.         }  
  142.   
  143.         @Override  
  144.         public <T> T get(Object key, Class<T> type) {  
  145.             // TODO Auto-generated method stub  
  146.             return null;  
  147.         }  
  148.       
  149.         @Override  
  150.         public ValueWrapper putIfAbsent(Object key, Object value) {  
  151.             // TODO Auto-generated method stub  
  152.             return null;  
  153.         }  
  154.   
  155. }  

到了這一步,大部分人會想在web.xml的啓動配置文件地方(context-param)加入了spring-redis.xml,讓項目啓動時加載這個配置文件吧,但是這樣啓動後註解不生效。

正確的做法是:web.xml中配置了servlet控制器:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. <servlet>  
  2.   <servlet-name>SpringMVC</servlet-name>  
  3.   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.   <init-param>  
  5.     <param-name>contextConfigLocation</param-name>  
  6.     <param-value>/WEB-INF/spring-mvc.xml</param-value>  
  7.   </init-param>  
  8.   <load-on-startup>1</load-on-startup>  
  9.   <async-supported>true</async-supported>  
  10. </servlet>  

在DispatcherServlet的初始化過程中,框架會在web應用的 WEB-INF文件夾下尋找名爲spring-mvc.xml的配置文件,如果不指定的話,默認是applicationContext.xml

只需要在spring-mvc.xml文件中引入spring-redis配置文件即可,正如spring-redis.xml中的啓用註解說的:<cache:annotation-driven cache-manager="cacheManager" />註解一定要聲明在spring主配置文件中才會生效。

spring-mvc.xml內容,省略了spring與spring MVC整合的那部分:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"    
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans      
  7.                         http://www.springframework.org/schema/beans/spring-beans-4.2.xsd      
  8.                         http://www.springframework.org/schema/context      
  9.                         http://www.springframework.org/schema/context/spring-context-4.2.xsd      
  10.                         http://www.springframework.org/schema/mvc      
  11.                         http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">  
  12.     <!-- 自動掃描該包,使SpringMVC認爲包下用了@controller註解的類是控制器 -->    
  13.     <context:component-scan base-package="com.cn" />    
  14.       
  15.     <!-- 引入同文件夾下的redis屬性配置文件 -->  
  16.     <import resource="spring-redis.xml"/>  
  17.       
  18. </beans>    

在service的實現類中:

[html] view plain copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. @Service  
  2. public class UserServiceImpl implements UserService{  
  3.   
  4.     @Autowired  
  5.     private UserBo userBo;  
  6.   
  7.     @Cacheable(value="common",key="'id_'+#id")  
  8.     public User selectByPrimaryKey(Integer id) {  
  9.         return userBo.selectByPrimaryKey(id);  
  10.     }  
  11.       
  12.     @CachePut(value="common",key="#user.getUserName()")  
  13.     public void insertSelective(User user) {  
  14.         userBo.insertSelective(user);  
  15.     }  
  16.   
  17.     @CacheEvict(value="common",key="'id_'+#id")  
  18.     public void deleteByPrimaryKey(Integer id) {  
  19.         userBo.deleteByPrimaryKey(id);  
  20.     }  
  21. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章