由于最近新上的项目很多模块没有做数据缓存,大量的请求都会到数据库去查询,为了减轻数据库的压力以及提高网站响应速度,所以在这里采用了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

【原】spring redis 缓存注解使用的更多相关文章

  1. spring redis @Cacheable注解使用部分错误及无效原因

    spring redis @Cacheable注解使用部分错误及无效原因 说明:     spring项目用到redis注解无效,解决问题中遇到一堆BUG,各种搜索,看了许多错误解决方案一一测试,对于 ...

  2. Spring Cache缓存注解

    目录 Spring Cache缓存注解 @Cacheable 键生成器 @CachePut @CacheEvict @Caching @CacheConfig Spring Cache缓存注解 本篇文 ...

  3. 使用AOP 实现Redis缓存注解,支持SPEL

    公司项目对Redis使用比较多,因为之前没有做AOP,所以缓存逻辑和业务逻辑交织在一起,维护比较艰难所以最近实现了针对于Redis的@Cacheable,把缓存的对象依照类别分别存放到redis的Ha ...

  4. Spring之缓存注解@Cacheable

    https://www.cnblogs.com/fashflying/p/6908028.html https://blog.csdn.net/syani/article/details/522399 ...

  5. Spring Boot缓存注解@Cacheable、@CacheEvict、@CachePut使用

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

  6. 深入理解Spring Redis的使用 (八)、Spring Redis实现 注解 自动缓存

    项目中有些业务方法希望在有缓存的时候直接从缓存获取,不再执行方法,来提高吞吐率.而且这种情况有很多.如果为每一个方法都写一段if else的代码,导致耦合非常大,不方便后期的修改. 思来想去,决定使用 ...

  7. 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存

    摘要: 主要针对Dao层的一些数据库查询的操作,数据实时性不强,直接加入缓存.当缓存中有的时候,就使用缓存中的数据.这样的方法,最终仅仅使用一个注解实现.对于之前的hibernate二级缓存使用,比较 ...

  8. spring与缓存注解,以及encache缓存使用

    随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...

  9. 27. Spring Boot 缓存注解详解: @Cacheable、@CachePut、 @CacheEvict、@Caching、@CacheConfig

     1.使用OGNL的命名规则来定义Key的值 @Cacheable(cacheNames = {"user"},key = "#root.methodName + '[' ...

随机推荐

  1. Android学习之Fragment解析

    1.定义     Fragment中文解释是碎片的意思,主要用在大屏幕设备上,例如平板电脑上,支持更加动态和灵活的UI设计.Fragment在你的应用中相当于是一个模块化和可重用的组件,因为Fragm ...

  2. openvswitch datapath 内核态流表创建过程(ovs_flow_cmd_new)

    datapath流表更新的入口函数都定义在dp_flow_genl_ops中,流表创建的入口函数是ovs_flow_cmd_new函数,通过该函数,我们可以一窥流表相关信息的建立. 1.ovs_flo ...

  3. elasticsearch 5.x Delete By Query API(根据条件删除)

    之前在 2.X版本里 这个Delete By Query功能被去掉了 因为官方认为会引发一些错误 如需使用 需要自己安装插件. bin/plugin install delete-by-query 需 ...

  4. [bug]微信小程序使用 <scroll-view> 和 box-shadow 引起页面抖动

    背景 为了实现点点点动态loading效果,并且方便使用(只需要给一个空元素加一个.loading),有如下代码: .loader { background-color: #fff; font-siz ...

  5. 【JS深入学习】——animationend 事件兼容性说明

    animationend 1.兼容性 animationend只有两种形式:animationend和webkitAnimationEnd webkitAnimationEnd 中 w 一定要小写,a ...

  6. java中线程池的几种实现方式

    1.线程池简介:    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建 ...

  7. python3中文件操作及编码

    #之前一直没明白文件处理中的w和wb的区别到底是什么,#在看过视频后才知道,原来在linux里面是没有区别的,#但是在windows里面就能够看出区别来了#下面来个例子: with open(&quo ...

  8. Fast Newman-FN算法以及模块度定义介绍

    一.社区的定义 Newman第一次提出模块度定义就是在2004年发表的这篇文章“fast algorithm for community structure in networks”,第一次用量化的公 ...

  9. ASP.NET 下使用特定身份完成windows服务的功能操作

    今天部署项目的发现一个问题: 在本地Win7系统下利用Web页面完成Windows服务的功能操作(启动.停止.安装.卸载)都是正常的,而部署到Server2008系统下,再使用Web页面完成windo ...

  10. jboss8+EJB3+MDB Queue

    1)在使用jboss8即WildFly进行MDB的试验时首先要在jboss8中配置jms 队列. 我使用的是修改配置文件的方式配置Jms Queue队列. 进入jboss8 安装目录的standalo ...