spring cache整合redis
2024-09-08 12:12:17
在项目中,我们经常需要将一些常用的数据使用缓存起来,避免频繁的查询数据库造成效率低下。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.进行测试
最新文章
- SQL Server 里的递归查询
- 基数排序 java 实现
- ssh(sturts2_spring_hibernate) 框架搭建之JPA代替hibernate
- 解决Mac下MySQL登录问题
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(转)
- BST &; Treap
- HDU 4816 Bathysphere(数学)(2013 Asia Regional Changchun)
- 2016 ACM/ICPC Asia Regional Dalian Online 1002/HDU 5869
- WF4与MVC结合示例
- UBUNTU 下设置全局 path变量
- Validform表单验证的完美解决方案,推荐给大家
- hiveQL求差集
- [开源项目] Android校验库 - FireEye
- 【学习笔记】Hibernate关联映射(Y2-1-6)
- 【CJOJ2499】【DP合集】棋盘 chess
- Java基础20:Java8新特性终极指南
- Win10+Ubuntu1604双系统
- C# 分析 IIS 日志(Log)
- POST、GET请求中文参数乱码问题
- 【Intel AF 2.1 学习笔记二】AF中的页面——Panel
热门文章
- Prism+WPF使用DependencyInjection实现AutoMapper的依赖注入功能
- Oracle体系结构一
- 【OI】蛇形填数题的深入探究
- Django学习day04随堂笔记
- 【PHP数据结构】在学数据结构和算法的时候我们究竟学的是啥?
- rabbitmqctl 命令行管理工具
- Dapr + .NET Core实战(四)发布和订阅
- 显式等待until传入自定义方法
- YbtOJ#463-序列划分【二分答案,线段树,dp】
- ES5新增方法--查找方法--forEach(),filter(),some()区别