亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

Redis整合Spring結合使用緩存實例

2020-02-17 14:53:32
字體:
來源:轉載
供稿:網友

????? 這是一篇關于Redis整合Spring結合使用緩存實例,在本文里介紹了如何在Spring中配置redis,并通過Spring中AOP的思想,將緩存的方法切入到有需要進入緩存的類或方法前面,下面就跟隨武林技術頻道的編輯一起來看看。
什么是Redis?
????? redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了master-slave(主從)同步。
它有什么特點?
(1)Redis數據庫完全在內存中,使用磁盤僅用于持久性。
(2)相比許多鍵值數據存儲,Redis擁有一套較為豐富的數據類型。
(3)Redis可以將數據復制到任意數量的從服務器。
Redis 優勢?
?(1)異??焖伲篟edis的速度非??欤棵肽軋绦屑s11萬集合,每秒約81000+條記錄。
?(2)支持豐富的數據類型:Redis支持最大多數開發人員已經知道像列表,集合,有序集合,散列數據類型。這使得它非常容易解決各種各樣的問題,因為我們知道哪些問題是可以處理通過它的數據類型更好。
(3)操作都是原子性:所有Redis操作是原子的,這保證了如果兩個客戶端同時訪問的Redis服務器將獲得更新后的值。
(4)多功能實用工具:Redis是一個多實用的工具,可以在多個用例如緩存,消息,隊列使用(Redis原生支持發布/訂閱),任何短暫的數據,應用程序,如Web應用程序會話,網頁命中計數等。
Redis 缺點?
(1)單線程
(2)耗內存
二、使用實例
本文使用maven+eclipse+sping
1、引入jar包

  <!--Redis start --> <dependency>   <groupId>org.springframework.data</groupId>   <artifactId>spring-data-redis</artifactId>   <version>1.6.1.RELEASE</version> </dependency> <dependency>   <groupId>redis.clients</groupId>   <artifactId>jedis</artifactId>   <version>2.7.3</version> </dependency>   <!--Redis end --> 

2、配置bean
在application.xml加入如下配置

<!-- jedis 配置 -->   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >      <property name="maxIdle" value="${redis.maxIdle}" />      <property name="maxWaitMillis" value="${redis.maxWait}" />      <property name="testOnBorrow" value="${redis.testOnBorrow}" />   </bean >  <!-- redis服務器中心 -->   <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >      <property name="poolConfig" ref="poolConfig" />      <property name="port" value="${redis.port}" />      <property name="hostName" value="${redis.host}" />      <property name="password" value="${redis.password}" />      <property name="timeout" value="${redis.timeout}" ></property>   </bean >   <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >      <property name="connectionFactory" ref="connectionFactory" />      <property name="keySerializer" >        <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />      </property>      <property name="valueSerializer" >        <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />      </property>   </bean >      <!-- cache配置 -->   <bean id="methodCacheInterceptor" class="com.mucfc.msm.common.MethodCacheInterceptor" >      <property name="redisUtil" ref="redisUtil" />   </bean >   <bean id="redisUtil" class="com.mucfc.msm.common.RedisUtil" >      <property name="redisTemplate" ref="redisTemplate" />   </bean > 

其中配置文件redis一些配置數據redis.properties如下:

#redis中心 redis.host=10.75.202.11 redis.port=6379 redis.password=123456 redis.maxIdle=100 redis.maxActive=300 redis.maxWait=1000 redis.testOnBorrow=true redis.timeout=100000  # 不需要加入緩存的類 targetNames=xxxRecordManager,xxxSetRecordManager,xxxStatisticsIdentificationManager # 不需要緩存的方法 methodNames=  #設置緩存失效時間 com.service.impl.xxxRecordManager= 60 com.service.impl.xxxSetRecordManager= 60 defaultCacheExpireTime=3600  fep.local.cache.capacity =10000 

要掃這些properties文件,在application.xml加入如下配置

 <!-- 引入properties配置文件 -->   <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   <property name="locations">     <list>       <value>classpath:properties/*.properties</value>       <!--要是有多個配置文件,只需在這里繼續添加即可 -->     </list>   </property> </bean> 

3、一些工具類
(1)RedisUtil
上面的bean中,RedisUtil是用來緩存和去除數據的實例

package com.mucfc.msm.common;  import java.io.Serializable; import java.util.Set; import java.util.concurrent.TimeUnit;  import org.apache.log4j.Logger; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations;  /**  * redis cache 工具類  *  */ public final class RedisUtil {   private Logger logger = Logger.getLogger(RedisUtil.class);   private RedisTemplate<Serializable, Object> redisTemplate;    /**    * 批量刪除對應的value    *    * @param keys    */   public void remove(final String... keys) {     for (String key : keys) {       remove(key);     }   }    /**    * 批量刪除key    *    * @param pattern    */   public void removePattern(final String pattern) {     Set<Serializable> keys = redisTemplate.keys(pattern);     if (keys.size() > 0)       redisTemplate.delete(keys);   }    /**    * 刪除對應的value    *    * @param key    */   public void remove(final String key) {     if (exists(key)) {       redisTemplate.delete(key);     }   }    /**    * 判斷緩存中是否有對應的value    *    * @param key    * @return    */   public boolean exists(final String key) {     return redisTemplate.hasKey(key);   }    /**    * 讀取緩存    *    * @param key    * @return    */   public Object get(final String key) {     Object result = null;     ValueOperations<Serializable, Object> operations = redisTemplate         .opsForValue();     result = operations.get(key);     return result;   }    /**    * 寫入緩存    *    * @param key    * @param value    * @return    */   public boolean set(final String key, Object value) {     boolean result = false;     try {       ValueOperations<Serializable, Object> operations = redisTemplate           .opsForValue();       operations.set(key, value);       result = true;     } catch (Exception e) {       e.printStackTrace();     }     return result;   }    /**    * 寫入緩存    *    * @param key    * @param value    * @return    */   public boolean set(final String key, Object value, Long expireTime) {     boolean result = false;     try {       ValueOperations<Serializable, Object> operations = redisTemplate           .opsForValue();       operations.set(key, value);       redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);       result = true;     } catch (Exception e) {       e.printStackTrace();     }     return result;   }    public void setRedisTemplate(       RedisTemplate<Serializable, Object> redisTemplate) {     this.redisTemplate = redisTemplate;   } } 

(2)MethodCacheInterceptor
切面MethodCacheInterceptor,這是用來給不同的方法來加入判斷如果緩存存在數據,從緩存取數據。否則第一次從數據庫取,并將結果保存到緩存 中去。

package com.mucfc.msm.common;  import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties;  import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.log4j.Logger;   public class MethodCacheInterceptor implements MethodInterceptor {   private Logger logger = Logger.getLogger(MethodCacheInterceptor.class);   private RedisUtil redisUtil;   private List<String> targetNamesList; // 不加入緩存的service名稱   private List<String> methodNamesList; // 不加入緩存的方法名稱   private Long defaultCacheExpireTime; // 緩存默認的過期時間   private Long xxxRecordManagerTime; //   private Long xxxSetRecordManagerTime; //    /**    * 初始化讀取不需要加入緩存的類名和方法名稱    */   public MethodCacheInterceptor() {     try {        File f = new File("D://lunaJee-workspace//msm//msm_core//src//main//java//com//mucfc//msm//common//cacheConf.properties");         //配置文件位置直接被寫死,有需要自己修改下        InputStream in = new FileInputStream(f);  //     InputStream in = getClass().getClassLoader().getResourceAsStream( //         "D://lunaJee-workspace//msm//msm_core//src//main//java//com//mucfc//msm//common//cacheConf.properties");       Properties p = new Properties();       p.load(in);       // 分割字符串       String[] targetNames = p.getProperty("targetNames").split(",");       String[] methodNames = p.getProperty("methodNames").split(",");        // 加載過期時間設置       defaultCacheExpireTime = Long.valueOf(p.getProperty("defaultCacheExpireTime"));       xxxRecordManagerTime = Long.valueOf(p.getProperty("com.service.impl.xxxRecordManager"));       xxxSetRecordManagerTime = Long.valueOf(p.getProperty("com.service.impl.xxxSetRecordManager"));       // 創建list       targetNamesList = new ArrayList<String>(targetNames.length);       methodNamesList = new ArrayList<String>(methodNames.length);       Integer maxLen = targetNames.length > methodNames.length ? targetNames.length           : methodNames.length;       // 將不需要緩存的類名和方法名添加到list中       for (int i = 0; i < maxLen; i++) {         if (i < targetNames.length) {           targetNamesList.add(targetNames[i]);         }         if (i < methodNames.length) {           methodNamesList.add(methodNames[i]);         }       }     } catch (Exception e) {       e.printStackTrace();     }   }    @Override   public Object invoke(MethodInvocation invocation) throws Throwable {     Object value = null;      String targetName = invocation.getThis().getClass().getName();     String methodName = invocation.getMethod().getName();     // 不需要緩存的內容     //if (!isAddCache(StringUtil.subStrForLastDot(targetName), methodName)) {     if (!isAddCache(targetName, methodName)) {       // 執行方法返回結果       return invocation.proceed();     }     Object[] arguments = invocation.getArguments();     String key = getCacheKey(targetName, methodName, arguments);     System.out.println(key);      try {       // 判斷是否有緩存       if (redisUtil.exists(key)) {         return redisUtil.get(key);       }       // 寫入緩存       value = invocation.proceed();       if (value != null) {         final String tkey = key;         final Object tvalue = value;         new Thread(new Runnable() {           @Override           public void run() {             if (tkey.startsWith("com.service.impl.xxxRecordManager")) {               redisUtil.set(tkey, tvalue, xxxRecordManagerTime);             } else if (tkey.startsWith("com.service.impl.xxxSetRecordManager")) {               redisUtil.set(tkey, tvalue, xxxSetRecordManagerTime);             } else {               redisUtil.set(tkey, tvalue, defaultCacheExpireTime);             }           }         }).start();       }     } catch (Exception e) {       e.printStackTrace();       if (value == null) {         return invocation.proceed();       }     }     return value;   }    /**    * 是否加入緩存    *    * @return    */   private boolean isAddCache(String targetName, String methodName) {     boolean flag = true;     if (targetNamesList.contains(targetName)         || methodNamesList.contains(methodName)) {       flag = false;     }     return flag;   }    /**    * 創建緩存key    *    * @param targetName    * @param methodName    * @param arguments    */   private String getCacheKey(String targetName, String methodName,       Object[] arguments) {     StringBuffer sbu = new StringBuffer();     sbu.append(targetName).append("_").append(methodName);     if ((arguments != null) && (arguments.length != 0)) {       for (int i = 0; i < arguments.length; i++) {         sbu.append("_").append(arguments[i]);       }     }     return sbu.toString();   }    public void setRedisUtil(RedisUtil redisUtil) {     this.redisUtil = redisUtil;   } } 

4、配置需要緩存的類或方法
在application.xml加入如下配置,有多個類或方法可以配置多個

<!-- 需要加入緩存的類或方法 --> <bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" >    <property name="advice" >      <ref local="methodCacheInterceptor" />    </property>    <property name="patterns" >      <list>       <!-- 確定正則表達式列表 -->        <value>com/.mucfc/.msm/.service/.impl/...*ServiceImpl.*</value >      </list>    </property> </bean > 

5、執行結果:
寫了一個簡單的單元測試如下:

@Test public void getSettUnitBySettUnitIdTest() {   String systemId = "CES";   String merchantId = "133";   SettUnit configSettUnit = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP");   SettUnit configSettUnit1 = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP");   boolean flag= (configSettUnit == configSettUnit1);   System.out.println(configSettUnit);   logger.info("查找結果" + configSettUnit.getBusinessType());    // localSecondFIFOCache.put("configSettUnit", configSettUnit.getBusinessType());  // String string = localSecondFIFOCache.get("configSettUnit");    logger.info("查找結果" + string); } 

這是第一次執行單元測試的過程:
MethodCacheInterceptor這個類中打了斷點,然后每次查詢前都會先進入這個方法

依次運行,發現沒有緩存,所以會直接去查數據庫

打印了出來的SQL語句:

第二次執行:
因為第一次執行時,已經寫入緩存了。所以第二次直接從緩存中取數據

3、取兩次的結果進行地址的對比:
發現兩個不是同一個對象,沒錯,是對的。如果是使用ehcache的話,那么二者的內存地址會是一樣的。那是因為redis和ehcache使用的緩存機制是不一樣的。ehcache是基于本地電腦的內存使用緩存,所以使用緩存取數據時直接在本地電腦上取。轉換成java對象就會是同一個內存地址,而redis它是在裝有redis服務的電腦上(一般是另一臺電腦),所以取數據時經過傳輸到本地,會對應到不同的內存地址,所以用==來比較會返回false。但是它確實是從緩存中去取的,這點我們從上面的斷點可以看到。

以上就是Redis整合Spring結合使用緩存實例,希望對大家的學習有所幫助,更多精彩內容,盡在https://js.Vevb.com。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲午夜av久久乱码| 国内外成人免费激情在线视频| 亚洲精品一区二三区不卡| 国内精品免费午夜毛片| 狠狠躁夜夜躁久久躁别揉| www.欧美精品一二三区| 欧美最猛黑人xxxx黑人猛叫黄| 国产91网红主播在线观看| 丰满岳妇乱一区二区三区| 亚洲人成在线观看| 欧美日韩免费区域视频在线观看| 91色p视频在线| 亚洲欧美国产高清va在线播| 欧美色另类天堂2015| 911国产网站尤物在线观看| 亚洲免费高清视频| 国产精品丝袜视频| 久久亚洲一区二区三区四区五区高| 川上优av一区二区线观看| 亚洲精品aⅴ中文字幕乱码| 欧美大尺度激情区在线播放| 国产精品男人的天堂| 日韩小视频网址| 亚洲网在线观看| 欧美性猛交xxxx乱大交蜜桃| 国产精品一区二区三区成人| 国产一区欧美二区三区| 伊人男人综合视频网| 国产精品久久久久久久久久久新郎| 久久精品国产成人| 久久精品99久久久香蕉| 亚洲国产日韩欧美在线99| 国产精品成人在线| 欧美激情综合色综合啪啪五月| 欧美性少妇18aaaa视频| 久久国产精品免费视频| 欧美日韩中国免费专区在线看| 亚洲国产精品成人精品| 国外日韩电影在线观看| 精品国产乱码久久久久久虫虫漫画| 日韩成人激情在线| 97视频在线播放| 欧美性感美女h网站在线观看免费| 亚洲一二在线观看| 欧美性猛交xxxx久久久| 日韩av成人在线观看| 色婷婷av一区二区三区久久| 亚洲第一中文字幕| 538国产精品一区二区在线| 国产欧美精品在线| 国产伦精品免费视频| 国产成人一区二区在线| 亚洲乱码一区av黑人高潮| 久久精品国产2020观看福利| 另类专区欧美制服同性| 国模私拍一区二区三区| www.日韩不卡电影av| 国产亚洲a∨片在线观看| 欧美日韩成人在线视频| 欧美激情a在线| 国产精品视频免费在线| 亚洲色图15p| 日韩精品在线免费观看视频| 久久天天躁狠狠躁夜夜爽蜜月| 国产精品欧美激情| 欧美性猛交xxxxx水多| 91精品国产成人www| www.国产一区| 91精品国产综合久久香蕉最新版| 国产精品直播网红| 国产精品久久久久久久久久东京| 久久久久成人精品| 国产精品白嫩初高中害羞小美女| 影音先锋欧美精品| 欧美一区二区三区艳史| 高清欧美一区二区三区| 午夜精品一区二区三区在线视频| 北条麻妃99精品青青久久| 日本成人精品在线| 欧美激情一级欧美精品| 精品久久香蕉国产线看观看gif| 久久久久久久久国产| 亚洲国产古装精品网站| 成人免费视频97| 久久久精品欧美| 91av中文字幕| 欧美三级免费观看| 亚洲第一视频网| 性欧美视频videos6一9| 国产视频精品自拍| 精品视频在线导航| 国产精品一区二区三区毛片淫片| 亚洲区一区二区| 国产欧美一区二区三区在线看| 丝袜亚洲欧美日韩综合| 色噜噜亚洲精品中文字幕| 欧美一二三视频| 亚洲视频视频在线| 亚洲国产精品系列| 成人中文字幕+乱码+中文字幕| 国内精品美女av在线播放| 日韩视频免费观看| 亚洲人成电影网站色…| 久久免费少妇高潮久久精品99| 国产91在线视频| 91精品久久久久久久久中文字幕| 国产美女搞久久| 在线色欧美三级视频| 久久精品一偷一偷国产| www.欧美精品一二三区| 国产在线精品播放| 亚洲免费成人av电影| 成人在线视频网| 久久亚洲精品一区二区| 亚洲免费一在线| 国产精品午夜国产小视频| 国产拍精品一二三| 色婷婷综合久久久久| 国产午夜精品理论片a级探花| 亚洲成人精品在线| 国产免费一区二区三区在线观看| 91免费电影网站| 国产成人aa精品一区在线播放| 国产精品一久久香蕉国产线看观看| 91wwwcom在线观看| 亚洲人成网站免费播放| 欧美日韩国产成人| 亚洲最大福利网站| 国产日韩在线一区| 国产精品久久久久久网站| 国产精品网址在线| 欧美日韩爱爱视频| 亚洲的天堂在线中文字幕| 亚洲图片在区色| 91精品国产91久久久久久不卡| 一区二区三区精品99久久| 九九久久国产精品| 2019av中文字幕| 国产欧美日韩精品丝袜高跟鞋| 欧美日韩国产91| 国产亚洲精品综合一区91| 亚洲欧美日韩成人| 中文字幕免费国产精品| 亚洲乱码一区av黑人高潮| 中文日韩电影网站| 亚洲大胆人体在线| 亚洲裸体xxxx| 亚洲黄色免费三级| 亚洲码在线观看| 中文字幕日韩高清| 亚洲国产精品va在线| 俺去啦;欧美日韩| 久久成人18免费网站| 久久久国产视频| 日韩av在线一区| 在线观看日韩视频| 久久久日本电影| 国产精品久久久久久久久久| 久久人人爽人人爽爽久久| 国产精品一区二区三区成人| 91免费在线视频网站| 欧美性极品少妇精品网站| 一区二区三区www| 日本一区二区三区在线播放|