Implementing Redis Cache Preheating in Spring Boot with AbstractCache Pattern
This tutorial demonstrates how to implement Redis cache preheating in Spring Boot using an abstract cache class, ApplicationContextAware utility, and CommandLineRunner to automatically load hot data on startup, with a complete NewsCache example using RedisTemplate.
What Is Cache Preheating?
Cache preheating is a strategy that proactively loads hotspot data into the cache after program startup or cache invalidation. When actual requests arrive, the hotspot data already exists in the cache, reducing cache penetration and cache breakdown while alleviating pressure on the SQL server.
Implementation
Abstract Cache Class
First, define an abstract base class that encapsulates the cache lifecycle. Subclasses implement the specific loading logic.
public abstract class AbstractCache {
protected abstract void init();
public abstract <T> T get();
public abstract void clear();
public void reload() {
clear();
init();
}
}Spring ApplicationContext Utility
A utility class implementing ApplicationContextAware to hold a static reference to the Spring ApplicationContext, enabling bean lookup from static contexts.
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtil.applicationContext = applicationContext;
}
public static ApplicationContext getContext() {
return applicationContext;
}
}Cache Preheat Handler
A CommandLineRunner implementation that runs after Spring Boot startup. It retrieves all beans of type AbstractCache and invokes their init() method. The @ConditionalOnProperty annotation makes the preheating optional, controlled by cache.init.enable=true in configuration.
@Component
@ConditionalOnProperty(name = {"cache.init.enable"}, havingValue = "true", matchIfMissing = false)
public class CachePreheatHandler implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
ApplicationContext context = ApplicationContextUtil.getContext();
Map<String, AbstractCache> beansOfType = context.getBeansOfType(AbstractCache.class);
for (Map.Entry<String, AbstractCache> cacheEntry : beansOfType.entrySet()) {
AbstractCache cache = context.getBean(cacheEntry.getValue().getClass());
cache.init();
}
}
}Configuration property:
cache.init.enable=trueUsage Example: News Hotspot Caching
The example uses a tb_news table containing Weibo hot-search sports entries.
Create a concrete implementation NewsCache extending AbstractCache. It uses RedisTemplate and a NewsService to load data. The init() method checks if the key exists; if not, it fetches the list from the service and stores it in Redis with a 30-minute TTL. The get() method reloads if the key is missing, ensuring data availability. The clear() method deletes the key.
@Component
@RequiredArgsConstructor
public class NewsCache extends AbstractCache {
private static final String NEWS_KEY = "news";
private final RedisTemplate<String, Object> redisTemplate;
private final NewsService newsService;
@Override
protected void init() {
if (Boolean.FALSE.equals(redisTemplate.hasKey(NEWS_KEY))) {
redisTemplate.opsForValue().set(NEWS_KEY, newsService.list(), 30, TimeUnit.MINUTES);
}
}
@Override
public <T> T get() {
if (Boolean.FALSE.equals(redisTemplate.hasKey(NEWS_KEY))) {
reload();
}
return (T) redisTemplate.opsForValue().get(NEWS_KEY);
}
@Override
public void clear() {
redisTemplate.delete(NEWS_KEY);
}
}After starting the application, the hotspot data appears in Redis.
Controller Access
A REST controller exposes the cached data via GET /news/cache, delegating to NewsCache.get().
@RestController
@RequestMapping("/news")
@RequiredArgsConstructor
public class NewsController {
private final NewsCache newsCache;
@GetMapping("/cache")
public List<News> list() {
return newsCache.get();
}
}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.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
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.
