Java 详解:如何实现一个 -redis- 缓存服务
@param key 存放的 key
@param value 存放的值/void putObject(String key, Object value);/*
将对象存放到缓存中
@param key 存放的 key
@param value 存放的值
@param expiration 过期时间,单位秒/void putObject(String key, Object value, int expiration);/*
从缓存中获取对象
@param key 要获取对象的 key
@return 如果存在,返回对象,否则,返回 null/Object pullObject(String key);/*
给缓存对象设置过期秒数
@param key 要获取对象的 key
@param expireSecond 过期秒数
@return 如果存在,返回对象,否则,返回 null/boolean expire(String key, int expireSecond);/*
获取缓存对象过期秒数
@param key 要获取对象的 key
@return 如果对象不存在,返回-2,如果对象没有过期时间,返回-1,否则返回实际过期时间/Long ttl(String key);/*
从缓存中删除对象
@param key 要删除对象的 key
@return 如果出现错误,返回 false,否则返回 true/boolean delObject(String key);/*
从缓存中清除对象*/void clearObject();}
定义序列号辅助类 com.x9710.common.redis.SerializeUtil
所有要保存到 redis 数据库中的对象需要先序列号为二进制数组,这个类的作用是将 Java 对象序列号为二级制数组或者将二级制数组反序列化为对象。
package com.x9710.common.redis;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/**
对象序列化工具类
/public class SerializeUtil {/*
将一个对象序列化为二进制数组
@param object 要序列化的对象,该必须实现 java.io.Serializable 接口
@return 被序列化后的二进制数组*/public static byte[] serialize(Object object) {try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(object);return baos.toByteArray();} catch (Exception e) {e.printStackTrace()
;}return null;}/**
将一个二进制数组反序列化为一个对象。程序不检查反序列化过程中的对象类型。
@param bytes 要反序列化的二进制数
@return 反序列化后的对象*/public static Object unserialize(byte[] bytes) {try {ByteArrayInputStream bais = new ByteArrayInputStream(bytes);ObjectInputStream ois = new ObjectInputStream(bais);return ois.readObject();} catch (Exception e) {e.printStackTrace();}return null;}}
实现 redis 缓存服务类 com.x9710.common.redis.impl.CacheServiceRedisImpl
package com.x9710.common.redis.impl;import com.x9710.common.redis.CacheService;import com.x9710.common.redis.RedisConnection;import com.x9710.common.redis.SerializeUtil;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import redis.clients.jedis.Jedis;/**
缓存服务 redis 实现类
*/public class CacheServiceRedisImpl implements CacheService {private static Log log = LogFactory.getLog(CacheServiceRedisImpl.class);private RedisConnection redisConnection;private Integer dbIndex;public void setRedisConnection(RedisConnection redisConnection) {this.redisConnection = redisConnection;}public void setDbIndex(Integer dbIndex) {this.dbIndex = dbIndex;}public void putObject(String key, Object value) {putObject(key, value, -1);}public void putObject(String key, Object value, int expiration) {Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);if (expiration > 0) {jedis.setex(key.getBytes(), expiration, SerializeUtil.serialize(value));} else {jedis.set(key.getBytes(), SerializeUtil.serialize(value));}} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}}public Object pullObject(String key) {
log.trace("strar find cache with " + key);Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);byte[] result = jedis.get(key.getBytes());if (result == null) {log.trace("can not find caceh with " + key);return null;} else {log.trace("find cache success with " + key);return SerializeUtil.unserialize(result);}} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}return null;}public boolean expire(String key, int expireSecond) {log.trace("strar set expire " + key);Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);return jedis.expire(key, expireSecond) == 1;} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}return false;}public Long ttl(String key) {log.trace("get set expire " + key);Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);return jedis.ttl(key);} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}return -2L;}public boolean delObject(String key) {log.trace("strar delete cache with " + key);Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);return jedis.del(key.getBytes()) > 0;} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}return false;}public void clearObject() {Jedis jedis = null;try {jedis = redisConnection.getJedis();jedis.select(dbIndex);jedis.flushDB();} catch (Exception e) {log.warn(e.getMessage(), e);} finally {if (jedis != null) {jedis.close();}}}}
编写测试用例
package com.x9710.common.redis.test;import com.x9710.common.redis.RedisConnection;import com.x9710.common.redis.impl.CacheServiceRedisImpl;import com.x9710.common.redis.test.domain.Student;import org.junit.Assert;import org.junit.Before;import org.junit.Test;/**
缓存服务测试类
*/public class RedisCacheTest {private CacheServiceRedisImpl cacheService;@Beforepublic void before() {RedisConnection redisConnection = RedisConnectionUtil.create();cacheService = new CacheServiceRedisImpl();cacheService.setDbIndex(2);cacheService.setRedisConnection(redisConnection);}@Testpublic void testStringCache() {String key = "name";String value = "grace";cacheService.putObject(key, value);String cachValue = (String) cacheService.pullObject(key);//检查从缓存中获取的字符串是否等于原始的字符串 Assert.assertTrue(value.equals(cachValue));
评论