Implementing Redis Cache Preheating in Spring Boot: A Practical Guide

This article explains cache preheating concepts and demonstrates a complete Spring Boot implementation using an abstract cache class, ApplicationContext utility, CommandLineRunner for startup loading, and a concrete NewsCache example with RedisTemplate to load hot data at startup, reducing cache penetration and database load.

IoT Full-Stack Technology
IoT Full-Stack Technology
IoT Full-Stack Technology
Implementing Redis Cache Preheating in Spring Boot: A Practical Guide

What Is Cache Preheating?

Cache preheating is a strategy that proactively loads hot data into the cache after application startup or cache invalidation. When real requests arrive, the hot data already resides 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 cache initialization, retrieval, clearing, and reloading. Concrete implementations will provide the actual caching logic.

public abstract class AbstractCache {
    /**
     * Initialize cache
     */
    protected abstract void init();
    /**
     * Get cached data
     * @param <T>
     * @return
     */
    public abstract <T> T get();
    /**
     * Clear cache
     */
    public abstract void clear();
    /**
     * Reload cache
     */
    public void reload() {
        clear();
        init();
    }
}

Spring Context Utility

A utility class implementing ApplicationContextAware to hold a static reference to the Spring ApplicationContext, enabling programmatic bean lookup.

@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;
    }
    /**
     * Get application context
     * @return
     */
    public static ApplicationContext getContext() {
        return applicationContext;
    }
}

Cache Preheat Handler

A CommandLineRunner implementation that runs after Spring Boot startup. It uses @ConditionalOnProperty so preheating is enabled only when cache.init.enable=true in configuration. The handler fetches all beans of type AbstractCache and invokes their init() method. Multiple implementations can be ordered with @Order.

@Component
@ConditionalOnProperty(name = {"cache.init.enable"}, havingValue = "true", matchIfMissing = false)
public class CachePreheatHandler implements CommandLineRunner {
    /**
     * Cache preheating
     * @param args
     * @throws Exception
     */
    @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();
        }
    }
}

Enable via configuration:

cache.init.enable=true

Usage Example: News Hotspot Caching

Assume a tb_news table storing Weibo hot-search sports data. The following implementation loads the news list into Redis at startup with a 30-minute TTL.

Database table screenshot
Database table screenshot

NewsCache Implementation

@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 hot data appears in Redis:

Redis data screenshot
Redis data screenshot

Controller Access

A REST endpoint retrieves the cached news list via NewsCache.get(), which automatically reloads if the key has expired.

@RestController
@RequestMapping("/news")
@RequiredArgsConstructor
public class NewsController {
    private final NewsCache newsCache;
    @GetMapping("/cache")
    public List<News> list() {
        return newsCache.get();
    }
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaRedisCachingSpring BootCommandLineRunnerCache PreheatingRedisTemplateApplicationContextAware
IoT Full-Stack Technology
Written by

IoT Full-Stack Technology

Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.