一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
简介
JetCache是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。 JetCache提供了比SpringCache更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了Cache
接口用于手工缓存操作。 当前有四个实现,RedisCache
、TairCache
(此部分未在github开源)、CaffeineCache
(in memory)和一个简易的LinkedHashMapCache
(in memory),要添加新的实现也是非常简单的。
全部特性:
- 通过统一的API访问Cache系统
- 通过注解实现声明式的方法缓存,支持TTL和两级缓存
- 通过注解创建并配置
Cache
实例 - 针对所有
Cache
实例和方法缓存的自动统计 - Key的生成策略和Value的序列化策略是可以配置的
- 分布式缓存自动刷新,分布式锁 (2.2+)
- 异步Cache API (2.2+,使用Redis的lettuce客户端时)
- Spring Boot支持
基本配置(使用Spring Boot)
添加依赖
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis-lettuce</artifactId>
<version>2.6.3</version>
</dependency>
复制代码
配置一个spring boot风格的application.yml文件,把他放到资源目录中
jetcache:
statIntervalMinutes: 60
areaInCacheName: false
hidePackages: com.f
local:
default:
type: caffeine
keyConvertor: fastjson
limit: 256
expireAfterWriteInMillis: 500
remote:
default:
type: redis.lettuce
expireAfterWriteInMillis: 5000
keyConvertor: fastjson
valueEncoder: kryo
valueDecoder: kryo
uri: redis://192.168.137.1:6379/1?timeout=100ms
复制代码
添加配置类EnableMethodCache,EnableCreateCacheAnnotation这两个注解分别激活Cached和CreateCache注解。
@EnableMethodCache(basePackages = "com.f")
@EnableCreateCacheAnnotation
@Configuration
public class CacheConfig {
@Bean(name = "redisClient")
@DependsOn(RedisLettuceAutoConfiguration.AUTO_INIT_BEAN_NAME)
public LettuceFactory redisClient() {
return new LettuceFactory("remote.default", RedisClient.class);
}
}
复制代码
@CreateCache使用,以及获取原生redis连接
@Component
@Accessors(fluent = true)
@Getter
@Slf4j
public class CacheTemplate {
private final RedisClient redisClient;
private final StatefulRedisConnection<String, String> connect;
private final StatefulRedisConnection<String, Object> objectConnection;
private final RedisCommands<String, String> sync;
private final RedisAsyncCommands<String, String> async;
private final RedisReactiveCommands<String, String> reactive;
private final RedisCommands<String, Object> syncObject;
private final RedisAsyncCommands<String, Object> asyncObject;
private final RedisReactiveCommands<String, Object> reactiveObject;
public CacheTemplate(final RedisClient redisClient) {
this.redisClient = redisClient;
this.connect = redisClient.connect();
this.objectConnection = redisClient.connect(KryoCodec.INSTANCE);
this.sync = connect.sync();
this.async = connect.async();
this.reactive = connect.reactive();
this.syncObject = objectConnection.sync();
this.asyncObject = objectConnection.async();
this.reactiveObject = objectConnection.reactive();
}
@PostConstruct
public void pingRedis() {
new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("redis-ping")).scheduleAtFixedRate(() -> log.debug("ping:{}", sync.ping()), 15, 150, TimeUnit.SECONDS);
}
@CreateCache(name = "common", expire = 30, cacheType = CacheType.REMOTE)
private Cache<String, Object> commonCache;
@CreateCache(name = "local", expire = 3, localLimit = 8096, cacheType = CacheType.LOCAL)
private Cache<String, Object> localCache;
@PreDestroy
public void destroy() {
connect.close();
objectConnection.close();
redisClient.shutdown();
}
}
复制代码
@Cached注解使用
@Cached(name = "perms", key = "#userId", localLimit = 1024, localExpire = 5, expire = 120, cacheType = CacheType.BOTH)
@Override
public Set<String> selectPermsByUserId(Long userId) {
return getBaseMapper().selectPermsByUserId(userId);
}
复制代码