Spring 整合 Redis
pom构建:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.1.2.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
spring配置文件(applicationContext.xml):
<context:property-placeholder location="classpath:redis.properties" />
<!-- redis config start -->
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="cacheManager" />
<!-- 配置JedisPoolConfig实例 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<property name="testOnReturn" value="${redis.testOnReturn}" />
<!-- <property name="testWhileIdle" value="true"/> -->
</bean>
<!-- 配置JedisConnectionFactory -->
<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="jedisPoolConfig" p:timeout="${redis.timeout}" />
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="JedisConnectionFactory" />
</bean>
<!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 这里可以配置多个redis -->
<!-- <bean class="com.cn.util.RedisCache"> <property name="redisTemplate"
ref="redisTemplate" /> <property name="name" value="default"/> </bean> -->
<bean class="com.github.util.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="common" />
<!-- common名称要在类或方法的注解中使用 -->
</bean>
</set>
</property>
</bean>
<!-- redis config end -->
开启Spring采用CGLIB代理
<!-- 配置使Spring采用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
redis.properties:
# Redis settings
redis.host=192.168.1.39
redis.port=6379
redis.pass=jay
redis.timeout=0
redis.maxIdle=300
redis.maxTotal=50
redis.maxWaitMillis=1000
redis.testOnBorrow=true
redis.testOnReturn=true
Java代码: 自己实现的缓存类 RedisCache
package com.github.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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;
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;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return this.redisTemplate;
}
@Override
public ValueWrapper get(Object key) {
System.out.println("get key");
final String keyf = key.toString();
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] key = keyf.getBytes();
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return toObject(value);
}
});
return (object != null ? new SimpleValueWrapper(object) : null);
}
@Override
public void put(Object key, Object value) {
System.out.println("put key");
final String keyf = key.toString();
final Object valuef = value;
final long liveTime = 10 * 6; //86400一天
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] keyb = keyf.getBytes();
byte[] valueb = toByteArray(valuef);
connection.set(keyb, valueb);
if (liveTime > 0) {
connection.expire(keyb, liveTime);
}
return 1L;
}
});
}
private byte[] toByteArray(Object obj) {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
oos.close();
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return bytes;
}
private Object toObject(byte[] bytes) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
obj = ois.readObject();
ois.close();
bis.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return obj;
}
@Override
public void evict(Object key) {
System.out.println("del key");
final String keyf = key.toString();
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.del(keyf.getBytes());
}
});
}
@Override
public void clear() {
System.out.println("clear key");
redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
connection.flushDb();
return "ok";
}
});
}
@Override
public <T> T get(Object key, Class<T> type) {
return null;
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
return null;
}
}
注意: spring配置文件中的
<bean class="com.github.util.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="common" />
<!-- common名称要在类或方法的注解中使用 -->
</bean>
name 的value 可以自定义 。后面方法注解的value要和这个对应
对Redis不懂的看这篇文章.
这里配置就完成了。可以直接在service方法上面开启注解: 有4个注解@Cacheable,@CachePut , @CacheEvict,@CacheConfig @Cacheable、@CachePut、@CacheEvict 注释介绍 @Cacheable 作用和配置方法 @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 @Cacheable 主要的参数 value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:这里和上面的name 的value对应,楼主这里写的是common @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如: @Cacheable(value=”testcache”,key=”#userName”) condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”)
--////////////////////////////////////////////////////////////////////////////////
@CachePut 作用和配置方法 @CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用 @CachePut 主要的参数 value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如: @Cacheable(value=”testcache”,key=”#userName”) condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”)
@CachePut 不同的是不管有没有缓存,都会调用方法.使用于 数据库的插入 //////////////////////////////////////////////////////
@CacheEvict 作用和配置方法 @CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空 @CacheEvict 主要的参数 value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如: @CachEvict(value=”testcache”,key=”#userName”) condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”) allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存例如: @CachEvict(value=”testcache”,allEntries=true) beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存例如: @CachEvict(value=”testcache”,beforeInvocation=true)
额外补充: 知道你们注意到一个问题没有,就是所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,不过不用担心,如果你在你的方法写别的名字,那么依然以方法的名字为准。 注释在类上面 @CacheConfig(cacheNames = "common")
- python爬虫入门(二)Opener和Requests
- python爬虫入门(三)XPATH和BeautifulSoup4
- python爬虫入门(四)利用多线程爬虫
- LOJ #115. 无源汇有上下界可行流
- 数据库改名系列(数据库名,逻辑名,物理文件名)
- BZOJ1468: Tree
- 洛谷P3806 【模板】点分治1
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
- 洛谷P3383 【模板】线性筛素数(Miller_Rabin)
- BZOJ3667: Rabin-Miller算法
- Numpy 修炼之道 (2)—— N维数组 ndarray
- python爬虫入门(五)Selenium模拟用户操作
- python爬虫入门(六) Scrapy框架之原理介绍
- lambda表达式杂谈
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- StringBuffer StringBulider String的区别
- 求X值问题
- python-剑指offer21-40
- Java8实战--引入流
- ThingJS数据对接方法介绍——Ajax
- python-剑指offer41-62
- 【python-opencv】读取、显示、写入图像
- WSL——windows上的linux子系统
- 【python-opencv】读取、显示、保存视频
- 超级账本——Hyperledger Fabric
- 【python-opencv】绘图(目标检测框及其置信度等)
- 哈希表:哈希值太大了,还是得用set
- 哈希表:今天你快乐了么?
- 简单二分法查找(binary search)
- 【python-opencv】鼠标作为画笔