在项目中,我们经常需要将一些常用的数据使用缓存起来,避免频繁的查询数据库造成效率低下。spring 为我们提供了一套基于注解的缓存实现,方便我们实际的开发。我们可以扩展spring的cache接口以达到使用redis来做缓存的效果。

步骤:

1.编写一个类用于实现   org.springframework.cache.Cache  这个接口

2.编写一个类实现  org.springframework.cache.CacheManager 这个接口或继承 org.springframework.cache.support.AbstractCacheManager这个类

3.在配置文件中进行配置。

代码:

1.使用redis实现spring的cache接口 -- 数据以hash的方式存入到redis中

package com.huan.redis.springcache;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; /**
* 自定义redis缓存
*
* @描述
* @作者 huan
* @时间 2016年6月26日 - 下午2:14:26
*/
public class RedisCache implements Cache { private JedisPool jedisPool;
/** 缓存的过期时间,单位是秒 */
private int timeouts; public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
} public int getTimeouts() {
return timeouts;
} public void setTimeouts(int timeouts) {
this.timeouts = timeouts;
} private String name; public void setName(String name) {
this.name = name;
} @Override
public String getName() {
return name;
} @Override
public Object getNativeCache() {
return jedisPool;
} @Override
public ValueWrapper get(Object key) {
ValueWrapper result = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String value = jedis.hget(getName(), (String) key);
if (value != null) {
result = new SimpleValueWrapper(value);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != jedis) {
jedis.close();
}
}
return result;
} @Override
public void put(Object key, Object value) {
String cacheKey = (String) key;
String cacheValue = (String) value;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hset(getName(), cacheKey, cacheValue);
jedis.expire(getName(), getTimeouts());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != jedis) {
jedis.close();
}
}
} @Override
public void evict(Object key) {
if (null != key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hdel(getName(), (String) key);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != jedis) {
jedis.close();
}
}
}
} @Override
public void clear() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hdel(getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != jedis) {
jedis.close();
}
}
}
}

2.实现自己的缓存管理器

package com.huan.redis.springcache;

import java.util.Collection;

import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager; /**
* 继承spring的抽象缓存管理器,用于实现我们自己的缓存管理
* @描述
* @作者 huan
* @时间 2016年6月26日 - 下午2:17:15
*/
public class RedisCacheManager extends AbstractCacheManager{ private Collection<? extends RedisCache> caches; public void setCaches(Collection<? extends RedisCache> caches) {
this.caches = caches;
} @Override
protected Collection<? extends Cache> loadCaches() {
return this.caches;
} }

3.配置文件中进行配置

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.huan.redis" />
<cache:annotation-driven cache-manager="cacheManager"/>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="testWhileIdle" value="true" />
<property name="minEvictableIdleTimeMillis" value="60000" />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="numTestsPerEvictionRun" value="-1" />
<property name="maxTotal" value="8" />
<property name="maxIdle" value="8" />
<property name="minIdle" value="0" />
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg ref="jedisPoolConfig" />
<constructor-arg value="192.168.1.5" />
</bean>
<bean id="cacheManager" class="com.huan.redis.springcache.RedisCacheManager">
<property name="caches">
<set>
<bean class="com.huan.redis.springcache.RedisCache">
<property name="jedisPool" ref="jedisPool" />
<property name="name" value="usersCache" />
<property name="timeouts" value="3600" />
</bean>
<bean class="com.huan.redis.springcache.RedisCache">
<property name="jedisPool" ref="jedisPool" />
<property name="name" value="booksCache" />
<property name="timeouts" value="3600" />
</bean>
</set>
</property>
</bean>
</beans>

 注意:1. <cache:annotation-driven cache-manager="cacheManager"/>这一句用于开启spring的缓存注解

2.redis.clients.jedis.JedisPool 用于配置redis的地址和端口,默认端口是6379,如果自己的redis不是这个端口,可以选择JedisPool中适当的构造方法进行配置

4.编写业务方法 -- UserService类中比较简单,就是UserServiceImpl中方法的申明。

package com.huan.redis.service;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; /**
* 测试业务员方法
* @描述
* @作者 huan
* @时间 2016年6月26日 - 下午3:20:58
*/
@Service
public class UserServiceImpl implements UserService {
/** 将数据放入到usersCache这个缓存中,缓存的key使用spirng的spel表达式获取值 */
@Override
@Cacheable(value = "usersCache", key = "#loginName")
public String getUser(String loginName) {
System.out.println("no user cache:" + loginName);
return loginName;
}
@Override
public String getUserNoCache(String loginName) {
return getUser(loginName);
}
@Override
@Cacheable(value = "booksCache", key = "#bookId")
public String addBook(String bookId) {
System.out.println("no book cache:" + bookId);
return bookId;
}
/** 使usersCache中的缓存key为#loginName这个值的缓存失效 */
@Override
@CacheEvict(value = "usersCache", key = "#loginName")
public void evictUser(String loginName) {
System.out.println("evict cache loginName:" + loginName);
}
}

5.进行测试

spring cache整合redis的更多相关文章

  1. SpringBoot--使用Spring Cache整合redis

    一.简介 Spring Cache是Spring对缓存的封装,适用于 EHCache.Redis.Guava等缓存技术. 二.作用 主要是可以使用注解的方式来处理缓存,例如,我们使用redis缓存时, ...

  2. 【Spring】17、spring cache 与redis缓存整合

    spring cache,基本能够满足一般应用对缓存的需求,但现实总是很复杂,当你的用户量上去或者性能跟不上,总需要进行扩展,这个时候你或许对其提供的内存缓存不满意了,因为其不支持高可用性,也不具备持 ...

  3. springboot整合spring @Cache和Redis

    转载请注明出处:https://www.cnblogs.com/wenjunwei/p/10779450.html spring基于注解的缓存 对于缓存声明,spring的缓存提供了一组java注解: ...

  4. Spring Boot2 系列教程(二十九)Spring Boot 整合 Redis

    经过 Spring Boot 的整合封装与自动化配置,在 Spring Boot 中整合Redis 已经变得非常容易了,开发者只需要引入 Spring Data Redis 依赖,然后简单配下 red ...

  5. Spring优雅整合Redis缓存

    “小明,多系统的session共享,怎么处理?”“Redis缓存啊!” “小明,我想实现一个简单的消息队列?”“Redis缓存啊!” “小明,分布式锁这玩意有什么方案?”“Redis缓存啊!” “小明 ...

  6. Spring Boot(八)集成Spring Cache 和 Redis

    在Spring Boot中添加spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframewo ...

  7. SpringBoot入门系列(七)Spring Boot整合Redis缓存

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查,.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/ ...

  8. Spring Boot 整合 Redis 和 JavaMailSender 实现邮箱注册功能

    Spring Boot 整合 Redis 和 JavaMailSender 实现邮箱注册功能 开篇 现在的网站基本都有邮件注册功能,毕竟可以通过邮件定期的给用户发送一些 垃圾邮件 精选推荐

  9. 使用Spring Cache集成Redis

    SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖 ...

随机推荐

  1. 经典多级时间轮定时器(C语言版)

    经典多级时间轮定时器(C语言版) 文章目录 经典多级时间轮定时器(C语言版) 1. 序言 2. 多级时间轮实现框架 2.1 多级时间轮对象 2.2 时间轮对象 2.3 定时任务对象 2.4 双向链表 ...

  2. 生产环境部署高可用Rancher

    环境准备: IP hostname role 192.168.200.150 nginx LB 192.168.200.151 master01-151 docker-ce/rke/helm/kube ...

  3. Maven专题3——生命周期与插件

    三套生命周期 Maven有3套相互独立的生命周期,用户可以调用某个生命周期的阶段,而不会对其他生命周期产生影响. 每个生命周期包含一些有先后顺序的阶段,后面的阶段依赖于前面的阶段,意味着用户调用后面的 ...

  4. FastAPI(5)- get 请求 - 查询参数 Query Parameters

    什么是查询参数? http://127.0.0.1:8000/get?name=xxx&age=18 http://127.0.0.1:8000/get?age=18&name=xxx ...

  5. C++快速读入

    使用C++的标准cin进行读入速度比较慢,尤其是在大数据的情况下,所以我们需要使用一种方法,按照字符读入,最后再"组装"成整数.由于字符读入比数字要快,所以这样做可以提高读入速度. ...

  6. Docker DevOps实战:GitLab+Jenkins(1)- GitLab容器搭建、使用SourceTree pull/push项目

    GitLab容器搭建 # 创建GitLab容器# --restart always #重启,容器自动重启# --privileged=true #容器内使用root权限 [root@localhost ...

  7. Shell系列(37)- while和until循环

    while循环 只要条件判断式成立则进行循环,并执行循环程序:一旦循环条件不成立,则终止循环 格式 while [ 条件判断式 ] do 程序 done 例子 需求:计算工具,1+2+--100的和 ...

  8. 制作python程序windows安装包(飞机大战源码)

    本文以飞机大战源码为例: 1.首先使用pyinstaller -w xxx.py打包   -w的意思是不显示命令行:飞机大战源码由多个.py文件以及一些图片,音乐文件组成,我们将main.py打包, ...

  9. centos7配置bind重启后错误解决

    最近研究centos7安装bind做DNS服务器,都配置好了后,重启后用systemctl status named 发现好多诸如以下错误:error (network unreachable) re ...

  10. 深入理解Python切片

    Python序列的切片很基础同时也很重要,最近看到一个[::-1]的表达,不明所以,查了一些资料并实际操作,对Python切片有了更深刻的认识,以下结合例子详细说明.先看下切片的基本语法,一般认为切片 ...