Mastering JetCache: Multi‑Level Caching with Spring Boot and Redis
This guide explains how to combine local and remote caches using Alibaba's JetCache in a Spring Boot project, covering dependency setup, configuration files, annotation‑based usage, advanced API methods, testing procedures, and common troubleshooting tips for a robust multi‑level caching solution.
Introduction
In real‑world applications, using only a local cache or only Redis is rarely sufficient; combining them to meet different business scenarios is essential. JetCache, an open‑source Java caching framework from Alibaba, helps achieve elegant multi‑level caching.
JetCache Overview
JetCache supports multiple cache types—local, distributed, and multi‑level—providing high performance, easy integration, cache warming, key prefixes, and seamless switching when used with Spring Cache.
https://github.com/alibaba/jetcache
Using JetCache
1. Add dependencies (example for a Spring Boot 2.6.13 project):
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>2.7.0</version>
</dependency>
<!-- Additional dependency for JetCache 2.7.x -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>2. Configure JetCache in application.yml (or application.properties) to set Redis address, thread pool, and cache options:
jetcache:
statIntervalMinutes: 15
areaInCacheName: false
local:
default:
type: linkedhashmap
keyConvertor: fastjson
remote:
default:
type: redis
keyConvertor: fastjson
broadcastChannel: projectA
valueEncoder: java
valueDecoder: java
poolConfig:
minIdle: 5
maxIdle: 20
maxTotal: 50
host: 127.0.0.1
port: 63793. Enable annotations in the Spring Boot main class:
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.example.jetcachedemo")4. Cache usage patterns
Annotation mode (recommended) using @Cached, @CacheUpdate, @CacheInvalidate:
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("getRemote")
@Cached(name="userCache:", key="#id", expire=3600, timeUnit=TimeUnit.SECONDS, cacheType=CacheType.REMOTE)
public User getRemote(Long id) { /* ... */ }
@GetMapping("getLocal")
@Cached(name="userCache:", key="#id", expire=3600, timeUnit=TimeUnit.SECONDS, cacheType=CacheType.LOCAL)
public User getLocal(Long id) { /* ... */ }
@GetMapping("getBoth")
@Cached(name="userCache:", key="#id", expire=3600, timeUnit=TimeUnit.SECONDS, cacheType=CacheType.BOTH)
public User getBoth(Long id) { /* ... */ }
@PostMapping("updateUser")
@CacheUpdate(name="userCache:", key="#user.id", value="#user")
public Boolean updateUser(@RequestBody User user) { return true; }
@PostMapping("deleteUser")
@CacheInvalidate(name="userCache:", key="#id")
public Boolean deleteUser(Long id) { return true; }
}Entity class User must implement Serializable:
@Data
public class User implements Serializable {
private Long id;
private String name;
private Integer age;
private Integer sex;
}API mode using @CreateCache (deprecated after 2.7):
@RestController
@RequestMapping("user2")
public class User2Controller {
@CreateCache(name="userCache:", expire=3600, timeUnit=TimeUnit.SECONDS, cacheType=CacheType.BOTH)
private Cache<Long, Object> userCache;
// get, update, delete methods similar to above
}Advanced API mode with CacheManager (available from 2.7):
@Configuration
public class JetcacheConfig {
@Autowired private CacheManager cacheManager;
private Cache<Long, Object> userCache;
@PostConstruct
public void init() {
QuickConfig qc = QuickConfig.newBuilder("userCache:")
.expire(Duration.ofSeconds(3600))
.cacheType(CacheType.BOTH)
.syncLocal(false)
.build();
userCache = cacheManager.getOrCreateCache(qc);
}
@Bean public Cache<Long, Object> getUserCache() { return userCache; }
}Controller can then autowire Cache<Long, Object> userCache and use it directly.
Testing
Method 1 (annotation mode) – Access localhost:8088/user/getRemote?id=1 to see the key stored in Redis, then .../getLocal?id=1 to verify that local cache falls back to remote data when needed.
Changing the cache type to LOCAL demonstrates that data is kept only in the local cache and not synchronized to Redis.
Method 2 (API mode) – Access localhost:8088/user2/get?id=4 to see both Redis and local entries; switching to CacheType.LOCAL removes the Redis entry.
Method 3 (Advanced API) – Calling localhost:8088/user3/get?id=11 stores the result in Redis via the programmatic cache.
Common Errors
ClassNotFoundException: com.alibaba.fastjson.JSON – add the FastJSON dependency.
NoClassDefFoundError: redis/clients/jedis/UnifiedJedis – add the Jedis dependency or downgrade JetCache to 2.6.5 or earlier.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.25</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>Source Code
https://gitee.com/wuhanxue/wu_study/tree/master/demo/jetcache-demo
(Copyright belongs to the original author, please delete if infringing)
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
