概述
1.前言
上篇文章,我们使用了spring自带的缓存机制cache,简单便捷,但同时又存在一定局限性,比如缓存大小扩展,过期时间设置,分布式缓存共享等,这篇文章我们就集成redis,使用redis来做spring的缓存。
2.redis特点和优势
2.1 redis的特点:
(1)Redis数据库完全在内存中,使用磁盘仅用于持久性。
(2)相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
(3)Redis可以将数据复制到任意数量的从服务器。
2.2 redis的优势:
(1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
(2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
3.依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
4.集成
4.1 重写Cache方法
RedisCache:
package com.tl.skyLine.cache;
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;
import java.io.*;
/**
* Created by tl on 17/2/28.
*/
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) {
final String keyf = (String) key;
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) {
final String keyf = (String) key;
final Object valuef = value;
final long liveTime = 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;
}
});
}
/**
* 描述 : <Object转byte[]>. <br>
* <p>
* <使用方法说明>
* </p>
*
* @param obj
* @return
*/
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;
}
/**
* 描述 : <byte[]转Object>. <br>
* <p>
* <使用方法说明>
* </p>
*
* @param bytes
* @return
*/
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) {
final String keyf = (String) key;
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.del(keyf.getBytes());
}
});
}
@Override
public void clear() {
redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "ok";
}
});
}
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Class<T> type) {
final String keyf = (String) key;
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 (T) object;
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
put(key, value);
return new SimpleValueWrapper(value);
}
}
4.2 修改配置文件
将spring-contex.xml配置文件中的
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="scacheManager"/>
<!--为了区别shiro中引用的id="cacheManager"-->
<bean id="scacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!--这边我们使用的是spring默认的缓存bean,我们也可以根据实际情况进行自定义-->
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="skyCache"/>
</set>
</property>
</bean>
修改为:
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="scacheManager"/>
<!--为了区别shiro中引用的id="cacheManager"-->
<bean id="scacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="com.tl.skyLine.cache.RedisCache">
<property name="redisTemplate" ref="redisTemplate"/>
<property name="name" value="skyCache"/>
</bean>
</set>
</property>
</bean>
redis-contex.xml配置文件参照之前的文章 点击打开链接
UserDaoImpl注解内容不做修改:
@Override
// value是必选项,定义了使用的缓存集合,key如果不定义时默认为方法的参数.key采用的是SpEL表达式
@Cacheable(value = "skyCache", key = "#username")
public User findOneByUsername(String username) {
Query query = new Query();
Criteria criteria = Criteria.where("username").is(username);
query.addCriteria(criteria);
return this.mongoTemplate.findOne(query, User.class);
}
5.测试
@Test
public void findOneByUsername() {
User use = userDao.findOneByUsername("skyLine");
}
在redis客户端查看key:
use对象就被保存在redis中!
最后
以上就是义气犀牛为你收集整理的架构之路之spring集成redis缓存1.前言2.redis特点和优势3.依赖4.集成5.测试的全部内容,希望文章能够帮你解决架构之路之spring集成redis缓存1.前言2.redis特点和优势3.依赖4.集成5.测试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复