最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談SpringCache與redis集成實(shí)現(xiàn)緩存解決方案

 更新時(shí)間:2017年12月15日 10:14:21   作者:宇的季節(jié)  
本篇文章主要介紹了淺談SpringCache與redis集成實(shí)現(xiàn)緩存解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

緩存可以說是加速服務(wù)響應(yīng)速度的一種非常有效并且簡單的方式。在緩存領(lǐng)域,有很多知名的框架,如EhCache 、Guava、HazelCast等。Redis作為key-value型數(shù)據(jù)庫,由于他的這一特性,Redis也成為一種流行的數(shù)據(jù)緩存工具。

在傳統(tǒng)方式下對于緩存的處理代碼是非常臃腫的。

例如:我們要把一個(gè)查詢函數(shù)加入緩存功能,大致需要三步。

一、在函數(shù)執(zhí)行前,我們需要先檢查緩存中是否存在數(shù)據(jù),如果存在則返回緩存數(shù)據(jù)

二、如果不存在,就需要在數(shù)據(jù)庫的數(shù)據(jù)查詢出來。

三、最后把數(shù)據(jù)存放在緩存中,當(dāng)下次調(diào)用此函數(shù)時(shí),就可以直接使用緩存數(shù)據(jù),減輕了數(shù)據(jù)庫壓力。

那么實(shí)現(xiàn)上面的三步需要多少代碼呢?下面是一個(gè)示例:

   

上圖中的紅色部分都是模板代碼,真正與這個(gè)函數(shù)有關(guān)的代碼卻只占了1/5,對于所有需要實(shí)現(xiàn)緩存功能的函數(shù),都需要加上臃腫的模板代碼??芍^是一種極不優(yōu)雅的解決方案。

那么如何讓臃腫的代碼重回清新的當(dāng)初呢?

AOP不就是專門解決這種模板式代碼的最佳方案嗎,幸運(yùn)的是我們不需要再自己實(shí)現(xiàn)切面了,SpringCache已經(jīng)為我們提供好了切面,我們只需要進(jìn)行簡單的配置,就可以重回當(dāng)初了,像下面這樣:

  

只需要加一個(gè)注解就可以了,對于原來的代碼連改都不需要改,是不是已經(jīng)躍躍欲試了?

對于配置SpringCache只需要三步:

第一步:加入相關(guān)依賴:

<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.6.0.RELEASE</version> 
</dependency> 
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId> 
  <version>3.3.2</version>
</dependency>

第二步:配置SpringCache,Redis連接等信息

applicationContext-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  xmlns:context="http://www.springframework.org/schema/context"  
  xmlns:mvc="http://www.springframework.org/schema/mvc"  
  xmlns:cache="http://www.springframework.org/schema/cache" 
  xsi:schemaLocation="http://www.springframework.org/schema/beans   
            http://www.springframework.org/schema/beans/spring-beans-4.2.xsd   
            http://www.springframework.org/schema/context   
            http://www.springframework.org/schema/context/spring-context-4.2.xsd   
            http://www.springframework.org/schema/mvc   
            http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
            http://www.springframework.org/schema/cache  
            http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
  
  <!-- 配置文件加載 -->
  <context:property-placeholder location="classpath:*.properties"/>
<cache:annotation-driven cache-manager="cacheManager"/>
  <!-- redis連接池 -->
  <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>
  <!-- 連接工廠 -->
  <bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
    p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>
  <!-- redis模板 -->
  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
     <property name="connectionFactory" ref="JedisConnectionFactory" />  
  </bean>
   
  <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
     <property name="caches">  
      <set>  
        <!-- 這里可以配置多個(gè)redis --> 
        <bean class="com.cky.rest.utils.RedisCache">  
           <property name="redisTemplate" ref="redisTemplate" />  
           <property name="name" value="content"/>  
           <!-- name對應(yīng)的名稱要在類或方法的注解中使用 --> 
        </bean> 
      </set>  
     </property>  
   </bean>  
</beans>

redis.properties文件:

# Redis settings 
# server IP 
redis.host=192.168.100.55 
# server port 
redis.port=6379 
# server pass 
redis.pass=
# use dbIndex 
redis.database=0 
#max idel instance of jedis
redis.maxIdle=300 
#if wait too long ,throw JedisConnectionException
redis.maxWait=3000 
#if true,it will validate before borrow jedis instance,what you get instance is all usefull
redis.testOnBorrow=true 

第三步,編寫Cache接口實(shí)現(xiàn)類

Spring對于緩存只是提供了抽象的接口,并且通過接口來調(diào)用功能,沒有具體的實(shí)現(xiàn)類,所以需要我們自己實(shí)現(xiàn)具體的操作。

在上面配置中可知,每個(gè)實(shí)現(xiàn)類都會(huì)注入一個(gè)redisTemplate實(shí)例,我們就可以通過redisTemplate來操作redis

package com.cky.rest.utils;
import java.io.Serializable;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisCache implements Cache {

  private RedisTemplate<String, Object> redisTemplate;
  private String name;

  @Override
  public void clear() {
    System.out.println("-------緩存清理------");
    redisTemplate.execute(new RedisCallback<String>() {
      @Override
      public String doInRedis(RedisConnection connection) throws DataAccessException {
        connection.flushDb();
        return "ok";
      }
    });
  }

  @Override
  public void evict(Object key) {
    System.out.println("-------緩存刪除------");
    final String keyf=key.toString();
    redisTemplate.execute(new RedisCallback<Long>() {
      @Override
      public Long doInRedis(RedisConnection connection) throws DataAccessException {
        return connection.del(keyf.getBytes());
      }
      
    });

  }

  @Override
  public ValueWrapper get(Object key) {
    System.out.println("------緩存獲取-------"+key.toString());
    final String keyf = key.toString();
    Object object = null;
    object = redisTemplate.execute(new RedisCallback<Object>() {
      @Override
      public Object doInRedis(RedisConnection connection) throws DataAccessException {
        byte[] key = keyf.getBytes();
        byte[] value = connection.get(key);
        if (value == null) {
          System.out.println("------緩存不存在-------");
          return null;
        }
        return SerializationUtils.deserialize(value);
      }
    });
    ValueWrapper obj=(object != null ? new SimpleValueWrapper(object) : null);
    System.out.println("------獲取到內(nèi)容-------"+obj);
    return obj;
  }

  @Override
  public void put(Object key, Object value) {
    System.out.println("-------加入緩存------");
    System.out.println("key----:"+key);
    System.out.println("key----:"+value);
    final String keyString = key.toString();
    final Object valuef = value;
    final long liveTime = 86400;
    redisTemplate.execute(new RedisCallback<Long>() {
      @Override
      public Long doInRedis(RedisConnection connection) throws DataAccessException {
        byte[] keyb = keyString.getBytes();
        byte[] valueb = SerializationUtils.serialize((Serializable) valuef);
        connection.set(keyb, valueb);
        if (liveTime > 0) {
          connection.expire(keyb, liveTime);
        }
        return 1L;
      }
    });

  }
  
  @Override
  public <T> T get(Object arg0, Class<T> arg1) {
    // TODO Auto-generated method stub
    return null;
  }
  
  @Override
  public String getName() {
    return this.name;
  }

  @Override
  public Object getNativeCache() {
    return this.redisTemplate;
  }
  
  @Override
  public ValueWrapper putIfAbsent(Object arg0, Object arg1) {
    // TODO Auto-generated method stub
    return null;
  }

  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;
  }
}

在配置過程中曾經(jīng)出現(xiàn)過兩次錯(cuò)誤:

1.Xxxx.ClassNotFoundException 最后發(fā)現(xiàn)是jar下載不完整,把maven本地倉庫的對應(yīng)jar包文件夾刪除完從新下載就好了

2.Xxxx.MethodNotFoundException 這種情況是版本不對,換成第一步中的版本就可以了

SpringCache中常見注解的使用:

@Cacheable注解

最常用的注解,會(huì)把被注解方法的返回值緩存。工作原理是:首先在緩存中查找,如果沒有執(zhí)行方法并緩存結(jié)果,然后返回?cái)?shù)據(jù)。此注解的緩存名必須指定,和cacheManager中的caches中的某一個(gè)Cache的name值相對應(yīng)??梢允褂胿alue或cacheNames指定。

如果沒有指定key屬性,spring會(huì)使用默認(rèn)的主鍵生成器產(chǎn)生主鍵。也可以自定義主鍵,在key中可以使用SpEL表達(dá)式。如下:

  @Cacheable(cacheNames=”content”,key=”#user.userId”)
  Public User getUser(User user){
    xxxxx
  } 

可以使用condition屬性,來給緩存添加條件,如下:

@Cacheable(cacheNames=”content”,key=”#user.userId”,condition=”#user.age<40”)
Public User getUser(User user){xxxxx}

@CachePut注解

先執(zhí)行方法,然后將返回值放回緩存??梢杂米骶彺娴母?。

@CacheEvict注解

該注解負(fù)責(zé)從緩存中顯式移除數(shù)據(jù),通常緩存數(shù)據(jù)都有有效期,當(dāng)過期時(shí)數(shù)據(jù)也會(huì)被移除。

此注解多了兩個(gè)屬性:

allEntries是否移除所有緩存條目。

beforeInvocation:在方法調(diào)用前還是調(diào)用后完成移除操作。true/false

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring中多配置文件及引用其他bean的方式

    Spring中多配置文件及引用其他bean的方式

    本文給大家介紹spring中多配置文件及引用其他bean的方式,涉及到spring配置文件的相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧
    2016-03-03
  • spring中AOP 注解開發(fā)示例詳解

    spring中AOP 注解開發(fā)示例詳解

    這篇文章主要介紹了spring中AOP注解開發(fā)的相關(guān)資料,文中介紹的很詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • spring實(shí)現(xiàn)靜態(tài)注入(類或者屬性)操作示例

    spring實(shí)現(xiàn)靜態(tài)注入(類或者屬性)操作示例

    這篇文章主要為大家介紹了spring實(shí)現(xiàn)靜態(tài)注入(類或者屬性)操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • SpringCloud組件性能優(yōu)化的技巧

    SpringCloud組件性能優(yōu)化的技巧

    這篇文章主要介紹了SpringCloud組件性能優(yōu)化的技巧,Springcloud?原始的配置,性能是很低的,大家可以使用?Jmeter?測試一下,QPS?不會(huì)到?50,要做到高并發(fā),需要做不少的配置優(yōu)化,需要的朋友可以參考下
    2023-09-09
  • Java中的Gradle與Groovy的區(qū)別及存在的關(guān)系

    Java中的Gradle與Groovy的區(qū)別及存在的關(guān)系

    這篇文章主要介紹了Java中的Gradle與Groovy的區(qū)別及存在的關(guān)系,Groovy是一種JVM語言,它可以編譯為與Java相同的字節(jié)碼,并且可以與Java類無縫地互操作,Gradle是Java項(xiàng)目中主要的構(gòu)建系統(tǒng)之一,下文關(guān)于兩者的詳細(xì)內(nèi)容,需要的小伙伴可以參考一下
    2022-02-02
  • Nacos封裝通用HttpClient詳解

    Nacos封裝通用HttpClient詳解

    這篇文章主要介紹了Nacos封裝通用HttpClient用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Spring Data JPA 實(shí)現(xiàn)多表關(guān)聯(lián)查詢的示例代碼

    Spring Data JPA 實(shí)現(xiàn)多表關(guān)聯(lián)查詢的示例代碼

    多表查詢在spring data jpa中有兩種實(shí)現(xiàn)方式,第一種是利用hibernate的級聯(lián)查詢來實(shí)現(xiàn),第二種是創(chuàng)建一個(gè)結(jié)果集的接口來接收連表查詢后的結(jié)果,這里介紹第二種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 如何利用Spring把元素解析成BeanDefinition對象

    如何利用Spring把元素解析成BeanDefinition對象

    這篇文章主要介紹了如何利用Spring把元素解析成BeanDefinition對象,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • 從Springboot項(xiàng)目中下載文件的具體過程

    從Springboot項(xiàng)目中下載文件的具體過程

    最近在做一個(gè)臨時(shí)的項(xiàng)目,APP端在檢測到程序有更新時(shí),需要去后臺(tái)下載新的安裝包,接下來通過本文給大家分享從Springboot項(xiàng)目中下載文件的具體過程,感興趣的朋友一起看看吧
    2021-07-07
  • Security 登錄認(rèn)證流程詳細(xì)分析詳解

    Security 登錄認(rèn)證流程詳細(xì)分析詳解

    本文Security登錄認(rèn)證流程詳細(xì)分析詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

吕梁市| 广水市| 尼木县| 靖江市| 汝城县| 沾化县| 青岛市| 阿巴嘎旗| 高雄市| 大兴区| 玉山县| 手机| 绍兴县| 陵水| 贡山| 麻城市| 佳木斯市| 平泉县| 垣曲县| 武冈市| 武乡县| 黄梅县| 方城县| 志丹县| 大方县| 城固县| 陕西省| 临漳县| 龙井市| 冷水江市| 沙河市| 龙江县| 神池县| 中卫市| 阿坝| 颍上县| 新野县| 上林县| 绥滨县| 巨野县| 拉萨市|