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

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
@Component
public class RedisCache implements Cache {

    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);

    /**
     * 区分名称
     */
    private String name;

    /**
     * redisTemplate
     */
    private RedisTemplate 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 get(Object o, Class 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定义的规则,进行删除缓存中对应的值。

你可能感兴趣的:(java-ee)