How to Configure Redis Caching with JetCache Annotations in ContiNew-Admin

ContiNew-Admin uses JetCache with Redisson to provide transparent method-level caching backed by Redis, configured through YAML files and activated via @EnableMethodCache on the main application class.

ContiNew-Admin is a modern Java admin framework that leverages JetCache to simplify distributed caching. By combining local Caffeine caches with a remote Redis backend via Redisson, the system achieves high-performance data access across clustered deployments. This guide explains how to configure Redis caching with JetCache annotations based on the actual implementation in the continew-org/continew-admin repository.

Enable Method-Level Caching

JetCache requires explicit activation to scan for caching annotations. In ContiNewAdminApplication.java, the @EnableMethodCache annotation triggers the framework to process @Cached, @CacheInvalidate, and related annotations within the specified base packages.

// continew-server/src/main/java/top/continew/admin/ContiNewAdminApplication.java
package top.continew.admin;

import com.alicp.jetcache.anno.config.EnableMethodCache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableMethodCache(basePackages = "top.continew.admin")
public class ContiNewAdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(ContiNewAdminApplication.class, args);
    }
}

This configuration ensures that any class within the top.continew.admin package hierarchy can use JetCache annotations without additional configuration.

Configure the Cache Stack

ContiNew-Admin implements a two-tier caching strategy that balances speed and consistency. The configuration resides in continew-server/src/main/resources/config/application-dev.yml (and application-prod.yml for production).

Local Cache (Caffeine)

The local tier provides microsecond-level access for data within the same JVM instance. Configure it under the jetcache.local block:

jetcache:
  statIntervalMinutes: 15
  local:
    default:
      type: caffeine
      keyConvertor: jackson
      expireAfterWriteInMillis: 7200000  # 2 hours

      limit: 1000

The limit: 1000 parameter restricts the local cache to 1000 entries, preventing memory pressure. The jackson key converter ensures complex objects serialize consistently.

Remote Redis Cache (Redisson)

The remote tier uses Redisson to connect to Redis, enabling data sharing across multiple application instances. Configure this under jetcache.remote:

jetcache:
  remote:
    default:
      type: redisson
      keyConvertor: jackson
      expireAfterWriteInMillis: 7200000
      broadcastChannel: ${spring.application.name}
      valueEncoder: java
      valueDecoder: java

The broadcastChannel setting ensures cache invalidation events propagate to all JVMs listening on the same channel, preventing stale data in clustered environments.

Connect to Redis

JetCache's Redisson client reuses standard Spring Redis configuration. Define the connection parameters in the same YAML profile:

spring:
  redis:
    host: localhost
    port: 6379
    password:      # leave empty for development

The Docker Compose setup in docker/docker-compose.yml spins up a Redis instance that matches these defaults for local development.

Annotate Service Methods

Once configured, apply JetCache annotations to service layer methods. The framework automatically intercepts calls to check the local cache first, then Redis, before executing the method body.

Cache Read Operations

Use @Cached to store method results. In UserServiceImpl.java, user lookups are cached with a custom expiration:

// continew-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java
import com.alicp.jetcache.anno.Cached;

@Service
public class UserServiceImpl implements UserService {

    @Override
    @Cached(name = "user:", key = "#id", expire = 3600)
    public UserVO getUserById(Long id) {
        return userMapper.selectById(id);
    }
}

The name parameter defines the cache region prefix, while key uses Spring Expression Language (SpEL) to incorporate method arguments. The expire value overrides the default 2-hour TTL with a 1-hour (3600-second) timeout.

Cache Invalidation

When data changes, remove stale entries using @CacheInvalidate. This ensures consistency between the database and both cache tiers:

@Override
@CacheInvalidate(name = "user:", key = "#user.id")
public void updateUser(UserDTO user) {
    userMapper.updateById(user);
}

This annotation triggers deletion from both the local Caffeine cache and the remote Redis instance.

Advanced JetCache Features

For high-traffic scenarios, ContiNew-Admin supports advanced JetCache patterns demonstrated in DashboardController.java.

Cache Penetration Protection

Prevent cache penetration attacks (where non-existent keys flood the database) using @CachePenetrationProtect:

@CachePenetrationProtect(name = "config:", key = "#key", timeout = 3000)
public ConfigVO getConfig(String key) {
    return configMapper.selectByKey(key);
}

This locks the cache key during the first thread's database load, blocking subsequent concurrent requests for the same key until the value is cached.

Automatic Refresh

Keep frequently accessed data fresh without blocking requests using @CacheRefresh:

@CacheRefresh(name = "config:", key = "#key", refresh = 600)
public ConfigVO getFreshConfig(String key) {
    return configMapper.selectByKey(key);
}

The background refresh runs every 600 seconds (10 minutes), reloading the value from the database while serving stale data during the update.

Summary

  • Enable caching by adding @EnableMethodCache(basePackages = "top.continew.admin") to ContiNewAdminApplication.java.
  • Configure tiers in application-dev.yml using type: caffeine for local caching and type: redisson for Redis distribution.
  • Set Redis connection under spring.redis in the same YAML file; JetCache automatically inherits these settings.
  • Apply annotations such as @Cached for reads and @CacheInvalidate for writes to maintain cache consistency.
  • Use broadcast channels to synchronize invalidation events across clustered JVM instances via the ${spring.application.name} channel.

Frequently Asked Questions

What is the difference between local and remote cache in ContiNew-Admin?

The local cache uses Caffeine to store data in the application's JVM memory, providing sub-millisecond access for single-instance hot data. The remote cache uses Redisson to store data in Redis, enabling microsecond-scale access across distributed instances. ContiNew-Admin checks the local tier first, then falls back to Redis, and finally executes the method if both miss.

How does ContiNew-Admin prevent stale cache data in clustered deployments?

The configuration sets broadcastChannel: ${spring.application.name} in the JetCache remote settings. When one instance invalidates or updates a cache entry, Redisson publishes the event to this channel. All other application instances listening on the same channel automatically evict their corresponding local Caffeine entries, ensuring consistency across the cluster.

Can I change the default cache expiration time?

Yes. While the default expireAfterWriteInMillis is 7200000 (2 hours) in application-dev.yml, you can override this per-method using the expire parameter in the @Cached annotation. Specify the value in seconds; for example, @Cached(expire = 3600) sets a 1-hour TTL for that specific cache region.

Do I need to configure Redisson separately from Spring Redis?

No. JetCache's Redisson implementation in ContiNew-Admin automatically reuses the connection settings defined under spring.redis in your YAML configuration. You only need to ensure the Redis server is accessible at the specified host and port; no additional Redisson-specific beans or configuration files are required.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →