【原】spring redis 緩存注解使用


  由於最近新上的項目很多模塊沒有做數據緩存,大量的請求都會到數據庫去查詢,為了減輕數據庫的壓力以及提高網站響應速度,所以在這里采用了spring 提供的注解+redis實現對數據的緩存,主要針對非熱點數據,例如 省市,銀行卡列表等做緩存,在這里主要是查詢做一個緩存實例。

 

  •  pom.xml  (加入spring和reids jar包)
 <!-- redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
        </dependency>

 

  • spring-redis.xml配置(通過配置線程池方式連接redis, 提供操作redis的api)
<!-- jedis 配置 -->

    <!-- redis連接池的配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="100" />
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="minIdle" value="${redis.minIdle}"/>
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <property name="testOnReturn" value="${redis.testOnReturn}"/>
    </bean>

    <!-- redis的連接池pool,不是必選項:timeout/password  -->
    <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.password}" />
        <property name="timeout" value="100000" />
        <property name="database" value="0"></property>
        <constructor-arg index="0" ref="jedisPoolConfig" />
    </bean>

<!-- 配置redis模板,需要注入到 RedisCacheManager by dada --> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <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> <!-- 配置緩存 by dada --> <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg ref="redisTemplate" /> <!--<property name="defaultExpiration" value="300"></property>--> <property name="usePrefix" value="true"></property> <property name="expires"> <util:map>
<!-- 指定key的時間為1500秒 -->
<entry key="get_bank_province_list" value="1500"></entry> <entry key="get_areas_bypid_list" value="1500"></entry> </util:map> </property> </bean>

 

  • 由於使用的是spring提供的注解方式實現redis緩存,所以需要在spring配置文件加上cache標簽,否則注解不會生效。
<!-- 啟用緩存注解功能,這個是必須的,否則注解不會生效,另外,該注解一定要聲明在spring主配置文件中才會生效,這個cacheManager
     必須指向redis配置里面的 RedisCacheManager-->
    <cache:annotation-driven cache-manager="cacheManager" />

 


 

配置好后如何使用:

  1. 在需要用到緩存的Service實現類方法加上對應的注解,例如一般查詢方法就是加上@Cacheable注意下面getBankProvince這個方法中我並沒有傳入參數,如果不帶參數查詢則要定義一個key(如何自定義key參見第2條),否則運行時候會出現無法找到key的錯誤,至於為什么報錯下次會詳細分析。
  2. 我在注解里定義了一個key  #root.methodName,代表的是默認使用方法名稱 getBankProvince 作為key的后綴, 則拼接后的完整key為 get_bank_province_list:getBankProvince
  3. 第一次請求 getBankProvince方法 Spring會做一個切面操作,也就是先請求redis,如果redis發現沒有這個key,則會查詢數據庫,查詢完成后會將數據存到redis。
  4. 第二次請求后由於第一次請求已經把數據存到了redis, 所以能從redis查詢到數據,則不會再去重復查詢數據庫了。
    /**
     * @Cacheable 
     * 應用到讀取數據的方法上,先從緩存中讀取,如果沒有再從DB獲取數據,然后把數據添加到緩存中
     * unless 表示條件表達式成立的話不放入緩存
     */
    @Cacheable(value = "get_bank_province_list",key = "#root.methodName")
    public List<SAreasEntity> getBankProvince() {  List<SAreasEntity> list = new ArrayList<SAreasEntity>(); List<SAreasItem> listItem = sAreasMapper.getBankProvince(); for(int i=0;i<listItem.size();i++){ SAreasEntity sareasEntity=new SAreasEntity(); SAreasItem sareasItem=listItem.get(i); sareasEntity.setId(sareasItem.getId()); sareasEntity.setName(sareasItem.getName()); sareasEntity.setPid(sareasItem.getPid()); sareasEntity.setCity_name(sareasItem.getCity_name()); list.add(sareasEntity); } return list; }

 

 說明

@Cacheable

應用到讀取數據的方法上,即可緩存的方法,如查找方法:先從緩存中讀取,如果沒有再調用方法獲取數據,然后把數據添加到緩存中。

 

除了上述使用方法參數作為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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM