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

时间:2021-11-20 20:36:49

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了。
“`java
@Data
@Component
public 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定义的规则,进行删除缓存中对应的值。