不知道这玩意的人,很喜欢自己实现缓存机制,因为查询嘛。
spring cache缓存可以有很多策略
我们经常使用的就是simple和redis
一切使用的源头,先引入maven包。
然后再配置文件中,配置需要什么缓存。
simple可以换成redis或者其他的缓存机制。
如果是simple,就比较简单,直接使用。
可以直接使用,走没走缓存,可以在方法里面打印log即可。
如果是redis,因为涉及到链接服务各种,这里需要额外的配置一下。
@EnableCaching
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheManager redisCacheManager = new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
// 默认策略,未配置的 key 会使用这个
this.getRedisCacheConfigurationWithTtl(3600),
// 指定 key 策略
this.getRedisCacheConfigurationMap()
);
redisCacheManager.setTransactionAware(true);
return redisCacheManager;
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16);
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
FstRedisSerializer kryoRedisSerializer = new FstRedisSerializer();
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(kryoRedisSerializer)
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
@Bean
public RedisTemplate<String, Object> limitRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
//StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory);
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setKeySerializer(new StringRedisSerializer());
//template.setHashKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
public class FstRedisSerializer implements RedisSerializer<Object> {
private static final byte[] EMPTY_ARRAY = new byte[0];
@Override
@SneakyThrows
public byte[] serialize(Object o) {
if (o == null) {
return EMPTY_ARRAY;
}
return new FSTSerializer().getConfig().asByteArray(o);
}
@Override
@SneakyThrows
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
return new FSTSerializer().getConfig().asObject(bytes);
}
private static boolean isEmpty(@Nullable byte[] data) {
return (data == null || data.length == 0);
}
}
public class FSTSerializer {
static class FSTDefaultStreamCoderFactory implements FSTConfiguration.StreamCoderFactory {
Field chBufField;
Field ascStringCacheField;
{
try {
chBufField = FSTStreamDecoder.class.getDeclaredField("chBufS");
ascStringCacheField = FSTStreamDecoder.class.getDeclaredField("ascStringCache");
} catch (Exception e) {
throw new IllegalStateException(e);
}
ascStringCacheField.setAccessible(true);
chBufField.setAccessible(true);
}
private FSTConfiguration fstConfiguration;
FSTDefaultStreamCoderFactory(FSTConfiguration fstConfiguration) {
this.fstConfiguration = fstConfiguration;
}
@Override
public FSTEncoder createStreamEncoder() {
return new FSTStreamEncoder(fstConfiguration);
}
@Override
public FSTDecoder createStreamDecoder() {
return new FSTStreamDecoder(fstConfiguration) {
@Override
public String readStringUTF() throws IOException {
try {
String res = super.readStringUTF();
chBufField.set(this, null);
return res;
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
public String readStringAsc() throws IOException {
try {
String res = super.readStringAsc();
ascStringCacheField.set(this, null);
return res;
} catch (Exception e) {
throw new IOException(e);
}
}
};
}
static ThreadLocal input = new ThreadLocal();
static ThreadLocal output = new ThreadLocal();
@Override
public ThreadLocal getInput() {
return input;
}
@Override
public ThreadLocal getOutput() {
return output;
}
}
private static class InstanceHolder {
private static final FSTConfiguration INSTANCE = FSTConfiguration.createDefaultConfiguration();
static {
INSTANCE.setStreamCoderFactory(new FSTDefaultStreamCoderFactory(INSTANCE));
}
}
public FSTConfiguration getConfig() {
return InstanceHolder.INSTANCE;
}
}
然后你就可以看到redis是否开始缓存了
这里多写一段redis服务
public class MyRedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
public MyRedisService() {
}
public Boolean set(String key, Object value) {
if (!StringUtils.isEmpty(key) && value != null) {
this.redisTemplate.opsForValue().set(key, value instanceof String ? value : JSON.toJSONString(value));
return Boolean.TRUE;
} else {
log.warn("参数为空[set]:{}->{}", key, value);
return Boolean.FALSE;
}
}
public <T> T get(String key, Class<T> type) {
if (StringUtils.isEmpty(key)) {
log.warn("参数为空[get]:{}->{}", key, type);
return null;
} else {
String value = (String) this.redisTemplate.opsForValue().get(key);
return type == String.class ? (T) value : JSON.parseObject(value, type);
}
}
public Boolean hashSet(String key, Object hKey, Object hValue) {
if (!StringUtils.isEmpty(key) && hValue != null && hKey != null) {
redisTemplate.opsForHash().put(key, hKey, hValue instanceof String ? hValue : JSON.toJSONString(hValue));
return Boolean.TRUE;
} else {
log.warn("参数为空[set]:{}->{}", key, hValue);
return Boolean.FALSE;
}
}
public <T> T hashGet(String key, Object hKey, Class<T> type) {
if (StringUtils.isEmpty(key) || Objects.isNull(hKey)) {
log.warn("参数为空[get]:{}->{}", key, type);
return null;
} else {
String value = (String) redisTemplate.opsForHash().get(key, hKey);
return type == String.class ? (T) value : JSON.parseObject(value, type);
}
}
public List hashGetList(String key, Class type) {
if (StringUtils.isEmpty(key)) {
log.warn("参数为空[get]:{}->{}", key);
return null;
} else {
List list = redisTemplate.opsForHash().values(key);
List listTrue = Lists.newArrayList();
for (Object o : list) {
listTrue.add(JSON.toJavaObject(JSONObject.parseObject(o.toString()), type));
}
return listTrue;
}
}
public Set<String> multiGetForSet(Set<String> keys) {
if (CollectionUtils.isEmpty(keys)) {
log.warn("参数为空[multiGet]:{}", keys);
return new HashSet();
} else {
return this.getForSet(this.stringRedisTemplate.opsForValue().multiGet(keys));
}
}
public Boolean del(String key) {
if (StringUtils.isEmpty(key)) {
log.warn("参数为空[del]:{}", key);
return Boolean.FALSE;
} else {
return this.redisTemplate.delete(key);
}
}
public Long del(Set<String> keys) {
if (CollectionUtils.isEmpty(keys)) {
log.warn("参数为空[del]:{}", keys);
return 0L;
} else {
return this.redisTemplate.delete(keys);
}
}
public Long addForSet(String key, String... ids) {
if (!StringUtils.isEmpty(key) && ids != null && ids.length != 0) {
return this.stringRedisTemplate.opsForSet().add(key, ids);
} else {
log.warn("参数为空[addForSet]:{}->{}", key, ids);
return 0L;
}
}
public Long addForSet(String key, Set<String> ids) {
if (CollectionUtils.isEmpty(ids)) {
log.warn("参数为空[addForSet]:{}->{}", key, ids);
return 0L;
} else {
return this.stringRedisTemplate.opsForSet().add(key, ids.toArray(new String[ids.size()]));
}
}
public Set<String> membersForSet(String key) {
if (StringUtils.isEmpty(key)) {
log.warn("参数为空[getForSet]:null");
return new HashSet();
} else {
return this.getForSet(this.stringRedisTemplate.opsForSet().members(key));
}
}
public Set<String> unionForSet(Set<String> keys) {
if (CollectionUtils.isEmpty(keys)) {
log.warn("参数为空[getForSet]:null");
return new HashSet();
} else if (keys.size() == 1) {
return this.getForSet(this.stringRedisTemplate.opsForSet().members(keys.iterator().next()));
} else {
Iterator<String> iter = keys.iterator();
String key = (String) iter.next();
HashSet otherKeys = new HashSet();
while (iter.hasNext()) {
otherKeys.add(iter.next());
}
return this.getForSet(this.stringRedisTemplate.opsForSet().union(key, otherKeys));
}
}
public Long delForSet(String key, String... ids) {
if (!StringUtils.isEmpty(key) && ids != null && ids.length != 0) {
return this.stringRedisTemplate.opsForSet().remove(key, ids);
} else {
log.warn("参数为空[delForSet]:{}->{}", key, ids);
return 0L;
}
}
public Long delForSet(String key, Set<String> ids) {
if (CollectionUtils.isEmpty(ids)) {
log.warn("参数为空[delForSet]:{}->{}", key, ids);
return 0L;
} else {
return this.stringRedisTemplate.opsForSet().remove(key, ids.toArray(new String[ids.size()]));
}
}
private Set<String> getForSet(Collection<String> list) {
if (CollectionUtils.isEmpty(list)) {
return new HashSet();
} else {
Set<String> set = (Set) list.stream().filter(Objects::nonNull).collect(Collectors.toSet());
return (Set) (CollectionUtils.isEmpty(set) ? new HashSet() : set);
}
}
}
原文:https://www.cnblogs.com/lzphu/p/12874265.html