spring 和 redis的集成(使用注解方式)

来源:互联网 发布:a星算法优化 编辑:程序博客网 时间:2024/06/10 22:31

spring 和 redis的集成(使用注解方式)

1.原因

  原因很简单,某些数据会被频繁的进行调用,之前是进行查询数据库,为了避免对数据库的压力,使用redis进行缓存,在调用接口的时候,先访问一下redis中是否存在,存在的话就在redis中进行取到,没有则进行查询数据库,并且在将查到的数据存到redis缓存中去。这让我想到了spring通过切面去定义的Cache不是可以完美的解决这个问题么。废话少说。

2.配置文件

需要配置spring的cache管理里面去,redis在spring的配置不用说了,主要是在SimpleCacheManager中进行注册,因为使用了另外的缓存机制。

<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">        <property name="caches">            <set>                <bean class="XXX.XXXX.XX.RedisCache">                    <property name="name" value="redis"/>                    <property name="redisTemplate"  ref="redisTemplate"/>                    <property name="liveTime" value="${redis.car.liveTime}"/><!-- 设置过期时间 -->                </bean>            </set>        </property>    </bean>

3.redisCache

 主要是实现了spring 的Cache接口,这样就可以Cache了。

@Data@Componentpublic class RedisCache implements Cache {    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);    /**     * 区分名称     */    private String name;    /**     * redisTemplate     */    private RedisTemplate<String, Object> redisTemplate;    /**     * 过期时间     */    private Long liveTime;    @Override    public String getName() {        return this.name;    }    @Override    public Object getNativeCache() {        return this.redisTemplate;    }    /**     * 得到数据     *     * @param key     * @return     */    @Override    public ValueWrapper get(Object key) {        logger.info("get cache, key:{}", key);        final String keyf = (String) key;        Object object = null;        object = redisTemplate.execute((RedisConnection connection) -> {            byte[] keyb = keyf.getBytes();            byte[] value = connection.get(keyb);            if (value == null) {                return null;            }            return toObject(value);        });        return (object != null ? new SimpleValueWrapper(object) : null);    }    /**     * 反序列化     *     * @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();        } catch (IOException ex) {            logger.error("IOException", ex);        } catch (ClassNotFoundException ex) {            logger.error("ClassNotFoundException", ex);        }        return obj;    }    @Override    public <T> T get(Object o, Class<T> aClass) {        return null;    }    /**     * key-value 的形式放入缓存     *     * @param key     * @param value     */    @Override    public void put(Object key, Object value) {        logger.info("put cache, key:{}", key);        final String keyf = (String) key;        final Object valuef = value;        redisTemplate.execute((RedisConnection connection) -> {            byte[] keyb = keyf.getBytes();            byte[] valueb = toByteArray(valuef);            connection.set(keyb, valueb);            if (liveTime > 0L) {                connection.expire(keyb, liveTime);            }            return 1L;        });    }    /**     * 序列化成二进制     *     * @param obj     * @return     */    private byte[] toByteArray(Object obj) {        byte[] bytes = null;        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();             ObjectOutputStream oos = new ObjectOutputStream(bos)) {            oos.writeObject(obj);            oos.flush();            bytes = bos.toByteArray();        } catch (IOException ex) {            logger.error("IOException", ex);        }        return bytes;    }    @Override    public ValueWrapper putIfAbsent(Object o, Object o1) {        return null;    }    /**     * 通过对应的key 进行删除缓存     *     * @param key     */    @Override    public void evict(Object key) {        logger.info("delete cache ,key:{}", key);        final String keyf = (String) key;        redisTemplate.execute((RedisConnection connection) -> {            return connection.del(keyf.getBytes());        });    }    /**     * 清除缓存     */    @Override    public void clear() {        redisTemplate.execute((RedisConnection connection) -> {            connection.flushDb();            return "success";        });    }}

4. @Cacheable @CacheEvint

 Cacheable注解是进入该方法的时候,去查看缓存中是否存在,如果存在的话,直接从缓存中去拿到数据,不进入方法。如果缓存中不存在,则进入该方法将方法的返回值按照一定的规则,进行保存到缓存中去。
CacheEvint注解则是清除缓存,返回类型可以为void,注解是通过传过来的参数和注解上的key定义的规则,进行删除缓存中对应的值。