flea-frame-cache使用之Redis接入

Redis 接入

参考

flea-frame-cache使用之Redis接入 源代码

依赖

jedis-3.0.1.jar

<!-- Java redis -->
<dependency>
     <groupId>redis.clients</groupId>
     <artifactId>jedis</artifactId>
     <version>3.0.1</version>
</dependency>

使用讲解

书接上篇博文,相关接口类和抽象类定义,不再赘述。

1. 定义Redis客户端接口类 RedisClient

/**
 * <p> Redis客户端对外接口 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public interface RedisClient {
    
    

    /**
     * <p> 往Redis塞数据 </p>
     *
     * @param key   数据键
     * @param value 数据值
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final String key, final String value);

    /**
     * <p> 往Redis赛数据(用于序列化对象) </p>
     *
     * @param key   数据键
     * @param value 数据值
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final byte[] key, final byte[] value);

    /**
     * <p> 往Redis塞数据 (可以带失效时间) </p>
     * <p> 注意 : (单位:s)</p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param expiry 失效时间(单位:s)
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final String key, final String value, final int expiry);

    /**
     * <p> 往Redis塞数据 (可以带失效时间,用于序列化对象) </p>
     * <p> 注意 : (单位:s)</p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param expiry 失效时间(单位:s)
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final byte[] key, final byte[] value, final int expiry);

    /**
     * <p> 往Redis塞数据 (可以带失效时间) </p>
     * <p> 注意:(单位:ms) </p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param expiry 失效时间(单位:ms)
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final String key, final String value, final long expiry);

    /**
     * <p> 往Redis塞数据 (可以带失效时间,用于序列化对象) </p>
     * <p> 注意:(单位:ms) </p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param expiry 失效时间(单位:ms)
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final byte[] key, final byte[] value, final long expiry);

    /**
     * <p> 往Redis塞数据 (带参数) </p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param params 参数
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final String key, final String value, SetParams params);

    /**
     * <p> 往Redis塞数据 (带参数,用于序列化对象) </p>
     *
     * @param key    数据键
     * @param value  数据值
     * @param params 参数
     * @return 状态码 (OK :成功)
     * @since 1.0.0
     */
    String set(final byte[] key, final byte[] value, SetParams params);

    /**
     * <p> 从Redis取数据 </p>
     *
     * @param key 数据键
     * @return 数据值
     * @since 1.0.0
     */
    String get(final String key);

    /**
     * <p> 从Redis取数据(用于获取序列化对象) </p>
     *
     * @param key 数据键
     * @return 数据值
     * @since 1.0.0
     */
    byte[] get(final byte[] key);

    /**
     * <p> 从Redis中删除数据 </p>
     *
     * @param key 数据键
     * @return 被删除key的数量
     * @since 1.0.0
     */
    Long del(final String key);

    /**
     * <p> 获取数据所在的Redis服务器ip(主机地址+端口) </p>
     *
     * @param key 数据键
     * @return 当前数据所在的Redis服务器ip
     * @since 1.0.0
     */
    String getLocation(final String key);

    /**
     * <p> 获取数据所在的Redis服务器ip(主机地址+端口) </p>
     *
     * @param key 数据键(字节数组)
     * @return 当前数据所在的Redis服务器ip
     * @since 1.0.0
     */
    String getLocation(final byte[] key);

    /**
     * <p> 获取数据所在的Redis服务器主机 </p>
     *
     * @param key 数据键
     * @return 数据所在的Redis服务器主机
     * @since 1.0.0
     */
    String getHost(final String key);

    /**
     * <p> 获取数据所在的Redis服务器主机 </p>
     *
     * @param key 数据键(字节数组)
     * @return 数据所在的Redis服务器主机
     * @since 1.0.0
     */
    String getHost(final byte[] key);

    /**
     * <p> 获取数据所在的Redis服务器主机端口 </p>
     *
     * @param key 数据键
     * @return 数据所在的Redis服务器主机端口
     * @since 1.0.0
     */
    Integer getPort(final String key);

    /**
     * <p> 获取数据所在的Redis服务器主机端口 </p>
     *
     * @param key 数据键(字节数组)
     * @return 数据所在的Redis服务器主机端口
     * @since 1.0.0
     */
    Integer getPort(final byte[] key);

    /**
     * <p> 获取数据所在的客户端类 </p>
     *
     * @param key 数据键
     * @return 数据所在的客户端类
     * @since 1.0.0
     */
    Client getClient(final String key);

    /**
     * <p> 获取数据所在的客户端类 </p>
     *
     * @param key 数据键
     * @return 数据所在的客户端类
     * @since 1.0.0
     */
    Client getClient(final byte[] key);

    /**
     * <p> 获取分布式Redis集群客户端连接池 </p>
     *
     * @return 分布式Redis集群客户端连接池
     * @since 1.0.0
     */
    ShardedJedisPool getJedisPool();

    /**
     * <p> 设置分布式Redis集群客户端 </p>
     *
     * @param shardedJedis 分布式Redis集群客户端
     * @since 1.0.0
     */
    void setShardedJedis(ShardedJedis shardedJedis);

    /**
     * <p> 获取分布式Redis集群客户端 </p>
     *
     * @return 分布是Redis集群客户端
     * @since 1.0.0
     */
    ShardedJedis getShardedJedis();

    /**
     * <p> 获取连接池名 </p>
     *
     * @return 连接池名
     * @since 1.0.0
     */
    String getPoolName();

    /**
     * <p> 设置连接池名 </p>
     *
     * @param poolName 连接池名
     * @since 1.0.0
     */
    void setPoolName(String poolName);
}

2. 定义Redis客户端实现类 FleaRedisClient

该类实现RedisClient接口, 其中分布式Jedis连接池 ShardedJedisPool 用于获取分布式Jedis对象 ShardedJedisShardedJedis可以自行根据初始化的算法,计算当前传入的数据键在某一台初始化的Redis服务器上,从而操作对数据的添加,查找,删除功能。

/**
 * <p> Flea Redis客户端类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class FleaRedisClient implements RedisClient {
    
    

    private ShardedJedisPool shardedJedisPool; // 分布式Jedis连接池

    private ShardedJedis shardedJedis; // 分布式Jedis对象

    private String poolName; // 连接池名

    /**
     * <p> Redis客户端构造方法 (默认) </p>
     *
     * @since 1.0.0
     */
    public FleaRedisClient() {
    
    
        this(null);
    }

    /**
     * <p> Redis客户端构造方法 </p>
     *
     * @param poolName 连接池名
     * @since 1.0.0
     */
    public FleaRedisClient(String poolName) {
    
    
        this.poolName = poolName;
        init();
    }

    /**
     * <p> 初始化 </p>
     *
     * @since 1.0.0
     */
    private void init() {
    
    
        if (StringUtils.isBlank(poolName)) {
    
    
            poolName = CacheConstants.FleaCacheConstants.DEFAUTL_POOL_NAME;
            RedisPool redisPool = RedisPool.getInstance();
            redisPool.initialize(); // 先初始化
            shardedJedisPool = redisPool.getJedisPool();
        } else {
    
    
            shardedJedisPool = RedisPool.getInstance(poolName).getJedisPool();
        }

    }

    @Override
    public String set(final String key, final String value) {
    
    
        return shardedJedis.set(key, value);
    }

    @Override
    public String set(byte[] key, byte[] value) {
    
    
        return shardedJedis.set(key, value);
    }

    @Override
    public String set(final String key, final String value, final int expiry) {
    
    
        return shardedJedis.setex(key, expiry, value);
    }

    @Override
    public String set(byte[] key, byte[] value, int expiry) {
    
    
        return shardedJedis.setex(key, expiry, value);
    }

    @Override
    public String set(String key, String value, long expiry) {
    
    
        return shardedJedis.psetex(key, expiry, value);
    }

    @Override
    public String set(byte[] key, byte[] value, long expiry) {
    
    
        return shardedJedis.psetex(key, expiry, value);
    }

    @Override
    public String set(final String key, final String value, final SetParams params) {
    
    
        return shardedJedis.set(key, value, params);
    }

    @Override
    public String set(byte[] key, byte[] value, SetParams params) {
    
    
        return shardedJedis.set(key, value, params);
    }

    @Override
    public String get(final String key) {
    
    
        return shardedJedis.get(key);
    }

    @Override
    public byte[] get(byte[] key) {
    
    
        return shardedJedis.get(key);
    }

    @Override
    public Long del(final String key) {
    
    
        return shardedJedis.del(key);
    }

    @Override
    public String getLocation(final String key) {
    
    
        return getLocationByKey(key);
    }

    @Override
    public String getLocation(byte[] key) {
    
    
        return getLocationByKey(key);
    }

    @Override
    public String getHost(final String key) {
    
    
        return getHostByKey(key);
    }

    @Override
    public String getHost(byte[] key) {
    
    
        return getHostByKey(key);
    }

    @Override
    public Integer getPort(final String key) {
    
    
        return getPortByKey(key);
    }

    @Override
    public Integer getPort(byte[] key) {
    
    
        return getPortByKey(key);
    }

    @Override
    public Client getClient(String key) {
    
    
        return getClientByKey(key);
    }

    @Override
    public Client getClient(byte[] key) {
    
    
        return getClientByKey(key);
    }

    /**
     * <p> 获取数据所在的Redis服务器ip(主机地址+端口) </p>
     *
     * @param key 数据键
     * @return 当前数据所在的Redis服务器ip
     * @since 1.0.0
     */
    private String getLocationByKey(Object key) {
    
    
        StringBuilder location = new StringBuilder();
        Client client = getClientByKey(key);
        if (ObjectUtils.isNotEmpty(client)) {
    
    
            location.append(client.getHost()).append(CommonConstants.SymbolConstants.COLON).append(client.getPort());
        }
        return location.toString();
    }

    /**
     * <p> 获取数据所在的Redis服务器主机 </p>
     *
     * @param key 数据键
     * @return 数据所在的Redis服务器主机
     * @since 1.0.0
     */
    private String getHostByKey(Object key) {
    
    
        Client client = getClientByKey(key);
        if (ObjectUtils.isNotEmpty(client)) {
    
    
            return client.getHost();
        }
        return null;
    }

    /**
     * <p> 获取数据所在的Redis服务器主机端口 </p>
     *
     * @param key 数据键
     * @return 数据所在的Redis服务器主机端口
     * @since 1.0.0
     */
    private Integer getPortByKey(Object key) {
    
    
        Client client = getClientByKey(key);
        if (ObjectUtils.isNotEmpty(client)) {
    
    
            return client.getPort();
        }
        return null;
    }

    /**
     * <p> 获取客户端类 </p>
     *
     * @param key 数据键
     * @return 客户端类
     * @since 1.0.0
     */
    private Client getClientByKey(Object key) {
    
    
        Client client = null;
        if (ObjectUtils.isNotEmpty(key)) {
    
    
            if (key instanceof String) {
    
    
                client = shardedJedis.getShard(key.toString()).getClient();
            } else if (key instanceof byte[]) {
    
    
                client = shardedJedis.getShard((byte[]) key).getClient();
            }
        }
        return client;
    }

    @Override
    public ShardedJedisPool getJedisPool() {
    
    
        return shardedJedisPool;
    }

    @Override
    public void setShardedJedis(ShardedJedis shardedJedis) {
    
    
        this.shardedJedis = shardedJedis;
    }

    @Override
    public ShardedJedis getShardedJedis() {
    
    
        return shardedJedis;
    }

    @Override
    public String getPoolName() {
    
    
        return poolName;
    }

    @Override
    public void setPoolName(String poolName) {
    
    
        this.poolName = poolName;
        init();
    }
}

该类初始化,可以看出我们使用了RedisPool, 下面来介绍一下

3. 定义Redis连接池 RedisPool

RedisPool 用于Redis相关配置信息的初始化,主要为了获取分布式Jedis连接池 ShardedJedisPool ,该类其中一个构造 如下:

/**
 * @param poolConfig 连接池配置信息
 * @param shards Jedis分布式服务器列表
 * @param algo 分布式算法
 */
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards,
      Hashing algo) 
/**
 * <p>  Flea Redis 连接池 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisPool {
    
    

    private final static ConcurrentMap<String, RedisPool> redisPools = new ConcurrentHashMap<String, RedisPool>();

    private String poolName; // 连接池名

    private ShardedJedisPool shardedJedisPool;

    private RedisPool(String poolName) {
    
    
        this.poolName = poolName;
    }

    /**
     * <p> 获取Redis连接池实例 (指定连接池名)</p>
     *
     * @param poolName 连接池名
     * @return Redis连接池实例对象
     * @since 1.0.0
     */
    public static RedisPool getInstance(String poolName) {
    
    
        if (!redisPools.containsKey(poolName)) {
    
    
            synchronized (redisPools) {
    
    
                if (!redisPools.containsKey(poolName)) {
    
    
                    RedisPool redisPool = new RedisPool(poolName);
                    redisPools.putIfAbsent(poolName, redisPool);
                }
            }
        }
        return redisPools.get(poolName);
    }

    /**
     * <p> 获取Redis连接池实例 (默认) </p>
     *
     * @return Redis连接池实例对象
     * @since 1.0.0
     */
    public static RedisPool getInstance() {
    
    
        return getInstance(CacheConstants.FleaCacheConstants.DEFAUTL_POOL_NAME);
    }

    /**
     * <p> 默认初始化 </p>
     *
     * @since 1.0.0
     */
    public void initialize() {
    
    
        if (!CacheConstants.FleaCacheConstants.DEFAUTL_POOL_NAME.equals(poolName)) {
    
    
            throw new RuntimeException("采用默认初始化,请使用RedisPool##getInstance()");
        }
        RedisConfig redisConfig = RedisConfig.getConfig();
        if (ObjectUtils.isEmpty(shardedJedisPool)) {
    
    
            shardedJedisPool = new ShardedJedisPool(redisConfig.getJedisPoolConfig(), redisConfig.getServers(), redisConfig.getHashingAlg());
        }
    }

    /**
     * <p> 分布式Redis集群客户端连接池 </p>
     *
     * @return 分布式Redis集群客户端连接池
     * @since 1.0.0
     */
    public ShardedJedisPool getJedisPool() {
    
    
        if (ObjectUtils.isEmpty(shardedJedisPool)) {
    
    
            throw new RuntimeException("获取分布式Redis集群客户端连接池失败:请先调用initialize初始化");
        }
        return shardedJedisPool;
    }

    /**
     * <p> 获取当前连接池名 </p>
     *
     * @return 连接池名
     * @since 1.0.0
     */
    public String getPoolName() {
    
    
        return poolName;
    }
}

4. 读取配置

flea-frame-cache读取redis.properties(Redis配置文件),用作初始化RedisPool

# Redis配置
# Redis服务器地址
redis.server=127.0.0.1:10001,127.0.0.1:10002,127.0.0.1:10003

# Redis服务登录密码
redis.password=huazie123,huazie123,huazie123

# Redis服务器权重分配
redis.weight=1,1,1

# Redis客户端socket连接超时时间
redis.connectionTimeout=2000

# Redis客户端socket读写超时时间
redis.soTimeout=2000

# Redis分布式hash算法
# 1 : MURMUR_HASH
# 2 : MD5
redis.hashingAlg=1

# Redis客户端连接池配置
# Redis客户端Jedis连接池最大连接数
redis.pool.maxTotal=8

# Redis客户端Jedis连接池最大空闲连接数
redis.pool.maxIdle=8

# Redis客户端Jedis连接池最小空闲连接数
redis.pool.minIdle=0

# Redis客户端Jedis连接池获取连接时的最大等待毫秒数
redis.pool.maxWaitMillis=2000

# Redis客户端Jedis连接池


5. 定义Redis Flea缓存类 RedisFleaCache

该类继承抽象Flea缓存类 AbstractFleaCache ,其构造方法可见如需要传入Redis客户端 RedisClient ,相关使用下面介绍:

/**
 * <p> Redis Flea缓存类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisFleaCache extends AbstractFleaCache {
    
    

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisFleaCache.class);

    private RedisClient redisClient; // Redis客户端

    /**
     * <p> 带参数的构造方法,初始化Redis Flea缓存类 </p>
     *
     * @param name        缓存主关键字
     * @param expiry      失效时长
     * @param redisClient Redis客户端
     */
    public RedisFleaCache(String name, long expiry, RedisClient redisClient) {
    
    
        super(name, expiry);
        this.redisClient = redisClient;
        cache = CacheEnum.Redis;
    }

    @Override
    public Object getNativeValue(String key) {
    
    
        if (LOGGER.isDebugEnabled()) {
    
    
            LOGGER.debug("RedisFleaCache##getNativeValue(String) KEY = {}", key);
        }
        // 反序列化
        return ObjectUtils.deserialize(redisClient.get(key.getBytes()));
    }

    @Override
    public void putNativeValue(String key, Object value, long expiry) {
    
    
        if (LOGGER.isDebugEnabled()) {
    
    
            LOGGER.debug("RedisFleaCache##putNativeValue(String, Object, long) KEY = {}", key);
            LOGGER.debug("RedisFleaCache##putNativeValue(String, Object, long) VALUE = {}", value);
            LOGGER.debug("RedisFleaCache##putNativeValue(String, Object, long) EXPIRY = {}s", expiry);
        }
        // 序列化
        if (ObjectUtils.isNotEmpty(value)) {
    
    
            byte[] valueBytes = ObjectUtils.serialize(value);
            if (expiry == CommonConstants.NumeralConstants.ZERO) {
    
    
                redisClient.set(key.getBytes(), valueBytes);
            } else {
    
    
                redisClient.set(key.getBytes(), valueBytes, (int) expiry);
            }
        }

    }

    @Override
    public void deleteNativeValue(String key) {
    
    
        if (LOGGER.isDebugEnabled()) {
    
    
            LOGGER.debug("RedisFleaCache##deleteNativeValue(String) KEY = {}", key);
        }
        redisClient.del(key);
    }

}

6. 定义Redis Flea缓存管理类 RedisFleaCacheManager

该类继承抽象Flea缓存管理类 AbstractFleaCacheManager,构造方法使用了Redis客户端代理类 RedisClientProxy 获取Redis客户端 RedisClient,这块后面介绍一下,下面看下Redis Flea缓存管理类

/**
 * <p> Redis Flea缓存管理类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisFleaCacheManager extends AbstractFleaCacheManager {
    
    

    private RedisClient redisClient;

    /**
     * <p> 默认构造方法,初始化Redis Flea缓存管理类 </p>
     *
     * @since 1.0.0
     */
    public RedisFleaCacheManager() {
    
    
        redisClient = RedisClientProxy.getProxyInstance();
    }

    @Override
    protected AbstractFleaCache newCache(String name, long expiry) {
    
    
        return new RedisFleaCache(name, expiry, redisClient);
    }

}

7. 定义Redis客户端代理类 RedisClientProxy

从如下可见,实际代理的是Flea Redis客户端 FleaRedisClient

/**
 * <p> RedisClient代理类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisClientProxy extends FleaProxy<RedisClient> {
    
    

    private final static ConcurrentMap<String, RedisClient> redisClients = new ConcurrentHashMap<String, RedisClient>();

    /**
     * <p> 获取RedisClient代理类 (默认)</p>
     *
     * @return RedisClient代理类
     * @since 1.0.0
     */
    public static RedisClient getProxyInstance() {
    
    
        return getProxyInstance(CacheConstants.FleaCacheConstants.DEFAUTL_POOL_NAME);
    }

    /**
     * <p> 获取RedisClient代理类 (指定连接池名)</p>
     *
     * @param poolName 连接池名
     * @return RedisClient代理类
     * @since 1.0.0
     */
    public static RedisClient getProxyInstance(String poolName) {
    
    
        if (!redisClients.containsKey(poolName)) {
    
    
            synchronized (redisClients) {
    
    
                if (!redisClients.containsKey(poolName)) {
    
    
                    // 新建一个Flea Redis客户端类, 用于被代理
                    RedisClient originRedisClient;
                    if(CacheConstants.FleaCacheConstants.DEFAUTL_POOL_NAME.equals(poolName)) {
    
    
                        originRedisClient = new FleaRedisClient();
                    } else {
    
    
                        originRedisClient = new FleaRedisClient(poolName);
                    }
                    RedisClient proxyRedisClient = newProxyInstance(originRedisClient.getClass().getClassLoader(), originRedisClient.getClass().getInterfaces(), new RedisClientInvocationHandler(originRedisClient));
                    redisClients.put(poolName, proxyRedisClient);
                }
            }
        }
        return redisClients.get(poolName);
    }

}

8. 定义Redis客户端调用处理类 RedisClientInvocationHandler

该类在RedisClientProxy中被调用,用于处理Flea Redis客户端类相应方法被代理调用前后的其他操作,本处主要实现代理前的分布式Jedis对象 ShardedJedis的获取,代理后的分布式Jedis对象 ShardedJedis的关闭,归还相关资源给分布式Jedis连接池 ShardedJedisPool

/**
 * <p> Redis客户端调用处理类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisClientInvocationHandler extends FleaInvocationHandler {
    
    

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisClientInvocationHandler.class);

    public RedisClientInvocationHandler(Object proxyObject) {
    
    
        super(proxyObject);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    

        if (ObjectUtils.isEmpty(proxyObject)) {
    
    
            throw new Exception("The proxyObject must be initialized");
        }

        if (!(proxyObject instanceof RedisClient)) {
    
    
            throw new Exception("The proxyObject must implement RedisClient interface");
        }

        RedisClient redisClient = (RedisClient) proxyObject;
        ShardedJedisPool jedisPool = redisClient.getJedisPool();
        if (ObjectUtils.isNotEmpty(jedisPool)) {
    
    
            redisClient.setShardedJedis(jedisPool.getResource());
            if (LOGGER.isDebugEnabled()) {
    
    
                LOGGER.debug("RedisClientInvocationHandler##invoke(Object, Method, Object[]) Get ShardedJedis = {}", redisClient.getShardedJedis());
            }
        }
        try {
    
    
            return super.invoke(proxy, method, args);
        } finally {
    
    
            ShardedJedis shardedJedis = redisClient.getShardedJedis();
            if (ObjectUtils.isNotEmpty(shardedJedis)) {
    
    
                // 使用后,关闭连接
                if (LOGGER.isDebugEnabled()) {
    
    
                    LOGGER.debug("RedisClientInvocationHandler##invoke(Object, Method, Object[]) Close ShardedJedis");
                }
                shardedJedis.close();
            }
        }
    }
}

哇,终于Redis接入差不多要完成了,下面一起开始启动单元测试吧

9. 缓存自测

@Test
    public void testRedisFleaCache() {
    
    
        try {
    
    
            AbstractFleaCacheManager manager = new RedisFleaCacheManager();
            AbstractFleaCache cache = manager.getCache("fleaparadetail");
            LOGGER.debug("Cache={}", cache);
            //#### 1.  简单字符串
//            cache.put("menu1", "huazie");
//            cache.get("menu1");
//            LOGGER.debug("CacheKey={}", cache.getCacheKey());
//            cache.delete("menu1");
            // 其他同memcached接入,可参考上一篇博文
            LOGGER.debug(cache.getCacheName() + ">>>" + cache.getCacheDesc());
        } catch (Exception e) {
    
    
            LOGGER.error("Exception:", e);
        }
    }

进阶练习

1. 定义Redis Spring缓存类 RedisSpringCache

该类继承抽象spring缓存 AbstractSpringCache,用于对接Spring; 从构造方法可见,该类初始化还是使用 Redis Flea缓存类 RedisFleaCache

/**
 * <p> Redis Spring缓存类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisSpringCache extends AbstractSpringCache {
    
    

    /**
     * <p> 带参数的构造方法,初始化Redis Spring缓存类 </p>
     *
     * @param name      缓存主关键字
     * @param fleaCache 具体缓存实现
     * @since 1.0.0
     */
    public RedisSpringCache(String name, IFleaCache fleaCache) {
    
    
        super(name, fleaCache);
    }

    /**
     * <p> 带参数的构造方法,初始化Redis Spring缓存类 </p>
     *
     * @param name        缓存主关键字
     * @param expiry      失效时长
     * @param redisClient Redis客户端
     * @since 1.0.0
     */
    public RedisSpringCache(String name, long expiry, RedisClient redisClient) {
    
    
        this(name, new RedisFleaCache(name, expiry, redisClient));
    }

}

2. 定义Redis Spring缓存管理类 RedisSpringCacheManager

该类继承抽象Spring缓存管理类AbstractSpringCacheManager,用于对接Spring; 基本实现同Redis Flea缓存管理类 RedisFleaCacheManager,唯一不同在于newCache的实现

/**
 * <p> Redis Spring缓存管理类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class RedisSpringCacheManager extends AbstractSpringCacheManager {
    
    

    private RedisClient redisClient;

    /**
     * <p> 默认构造方法,初始化Redis Spring缓存管理类 </p>
     *
     * @since 1.0.0
     */
    public RedisSpringCacheManager() {
    
    
        redisClient = RedisClientProxy.getProxyInstance();
    }

    @Override
    protected AbstractSpringCache newCache(String name, long expiry) {
    
    
        return new RedisSpringCache(name, expiry, redisClient);
    }

}

3. Spring配置

<!--
    配置缓存管理RedisSpringCacheManager
    配置缓存时间 configMap (key缓存对象名称 value缓存过期时间)
-->
<bean id="redisSpringCacheManager" class="com.huazie.frame.cache.redis.RedisSpringCacheManager">
    <property name="configMap">
        <map>
            <entry key="fleaparadetail" value="86400"/>
        </map>
    </property>
</bean>

<!-- 开启缓存 -->
<cache:annotation-driven cache-manager="redisSpringCacheManager" proxy-target-class="true"/>

4. 缓存自测

    private ApplicationContext applicationContext;

    @Before
    public void init() {
    
    
        applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        LOGGER.debug("ApplicationContext={}", applicationContext);
    }

	@Test
    public void testRedisSpringCache() {
    
    
        try {
    
    
            AbstractSpringCacheManager manager = (RedisSpringCacheManager) applicationContext.getBean("redisSpringCacheManager");
            LOGGER.debug("RedisCacheManager={}", manager);

            AbstractSpringCache cache = manager.getCache("fleaparadetail");
            LOGGER.debug("Cache={}", cache);

            //#### 1.  简单字符串
//			cache.put("menu1", "huazie");
//            cache.get("menu1");
//            cache.get("menu1", String.class);

            //#### 2.  简单对象(要是可以序列化的对象)
//			String user = new String("huazie");
//			cache.put("user", user);
//			LOGGER.debug(cache.get("user", String.class));
//            cache.get("FLEA_RES_STATE");
            cache.clear();

            //#### 3.  List塞对象
//			List<String> userList = new ArrayList<String>();
//			userList.add("huazie");
//			userList.add("lgh");
//			cache.put("user_list", userList);

//			LOGGER.debug(cache.get("user_list",userList.getClass()).toString());

        } catch (Exception e) {
    
    
            LOGGER.error("Exception:", e);
        }
    }

好了, 现在算是Redis接入全部完成了,准备洗洗睡了!!!
一起期待我的下一篇博文 flea-frame-cache使用之整合Memcached和Redis接入

猜你喜欢

转载自blog.csdn.net/u012855229/article/details/99702460
今日推荐