Integrating Redis with Spring Boot for Caching, Lua Scripting, and Session Sharing

Integrating Redis as a Cache in Spring Boot

To use Redis as a caching layer in Spring Boot, include the spring-boot-starter-cache and spring-boot-starter-data-redis dependencies. Spring Boot auto-configures a RedisTemplate and, when caching is enabled, a RedisCacheManager.

Required Dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Basic Configuration (application.properties)

spring.redis.host=192.168.66.128
spring.redis.port=6380
spring.cache.cache-names=user-cache

Enable caching by adding @EnableCaching to the main application class:

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Spring Boot automatically configures a RedisCacheManager using default settings. For custom behavior—such as TTL or serialization—define your own CacheManager bean.

Using Cache Annotations

  • @CacheConfig: Class-level annotation to set a default cache name.
  • @Cacheable: Caches method return values. The key can be cusotmized using SpEL.
    @Cacheable(cacheNames = "user-cache", key = "#userId")
    public User fetchUser(Long userId) {
        return userRepository.findById(userId);
    }
    
  • @CachePut: Updates the cache after method execution (e.g., after updating an entity).
    @CachePut(cacheNames = "user-cache", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }
    
  • @CacheEvict: Removes entries from the cache (e.g., on deletion).
    @CacheEvict(cacheNames = "user-cache", key = "#id")
    public void removeUser(Long id) {
        userRepository.deleteById(id);
    }
    

Executing Lua Scripts in Redis via Spring Boot

Lua scripts enable atomic, multi-command operations directly on the Redis server, reducing round trips and ensuring consistency.

Example Lua Script (sum.lua)

local x = tonumber(ARGV[1])
local y = tonumber(ARGV[2])
return x + y

Executing from Java

@Service
public class MathService {

    private final StringRedisTemplate redisTemplate;
    private final ResourceLoader resourceLoader;

    public MathService(StringRedisTemplate redisTemplate, ResourceLoader resourceLoader) {
        this.redisTemplate = redisTemplate;
        this.resourceLoader = resourceLoader;
    }

    public Long executeSumScript(Long a, Long b) {
        RedisScript<Long> script = RedisScript.of(
            "local x = tonumber(ARGV[1]); local y = tonumber(ARGV[2]); return x + y",
            Long.class
        );
        return redisTemplate.execute(script, Collections.emptyList(), a, b);
    }

    public Long executeFromFile(Long a, Long b) throws IOException {
        Resource scriptResource = resourceLoader.getResource("classpath:sum.lua");
        String scriptText = new String(scriptResource.getInputStream().readAllBytes());
        RedisScript<Long> script = RedisScript.of(scriptText, Long.class);
        return redisTemplate.execute(script, Collections.emptyList(), a, b);
    }
}

Common Use Cases for Lua in Redis

  • Atomic counters: INCRBY within a script ensures thread safety.
  • Codnitional updates: Update a value only if it meets certain criteria.
  • Distributed locks: Use SET key value NX PX timeout atomically.
  • Batch data processing: Aggregate or transform multiple keys without client-side loops.

Custom Redis Configuration for Caching

For proper object serialization and TTL control:

@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10))
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Object.class)))
            .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .build();
    }
}

Enabling Redis-Based Session Sharing

To share HTTP sessions across multiple instances (e.g., in a microservices architecture), use Spring Session with Redis.

Add Dependency

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

Enable Redis Session

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 2592000) // 30 days
public class SessionConfig {
    // Optional: customize RedisTemplate if needed
}

Test Session Sharing

Create a controller to store and retrieve session attributes:

@RestController
@RequestMapping("/api/session")
public class SessionController {

    @GetMapping("/store")
    public String storeUrl(HttpServletRequest request) {
        request.getSession().setAttribute("url", request.getRequestURL().toString());
        return "Stored";
    }

    @GetMapping("/info")
    public Map<String, Object> getSessionInfo(HttpServletRequest request) {
        return Map.of(
            "id", request.getSession().getId(),
            "url", request.getSession().getAttribute("url")
        );
    }
}

Run two instances on different ports (e.g., 8080 and 9090). After storing a value on port 8080, retrieving it from port 9090 returns the same session ID and data—confirming session sharing via Redis.

Tags: Spring Boot Redis Caching Lua Session Sharing

Posted on Sat, 09 May 2026 21:29:26 +0000 by katlis