# Kickoff Java Project — Redis/Cache Module
Redis caching module (conditional: Redis=Yes).
Reference: Janus `janus-webapp/src/main/java/.../config/cache/` and `janus-core/src/main/java/.../config/cache/`.
---
## Dependencies
**webapp POM:**
```xml
org.springframework.bootspring-boot-starter-data-redis
org.springframework.bootspring-boot-starter-cache
```
**core POM:**
```xml
org.springframework.bootspring-boot-starter-cache
```
---
## CacheConfiguration
Located in webapp: `src/main/java//webapp/config/cache/CacheConfiguration.java`
```java
@Configuration
@EnableCaching
@EnableConfigurationProperties(CacheConfigurationProperties.class)
@ConditionalOnProperty(name = "humand..cache.enabled", havingValue = "true", matchIfMissing = true)
public class CacheConfiguration {
@Bean
public RedisCacheManager cacheManager(
RedisConnectionFactory connectionFactory, CacheConfigurationProperties cacheProperties) {
Duration ttl = Duration.ofMinutes(cacheProperties.ttlMinutes());
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(ttl)
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(cacheConfig)
.build();
}
}
```
---
## CacheConfigurationProperties
Located in webapp: `src/main/java//webapp/config/cache/CacheConfigurationProperties.java`
```java
@ConfigurationProperties("humand..cache")
public record CacheConfigurationProperties(boolean enabled, int ttlMinutes) {}
```
---
## CacheNames
Located in core: `src/main/java//core/config/cache/CacheNames.java`
```java
public final class CacheNames {
private CacheNames() {}
public static final String SAMPLE_CACHE = ":v1:SAMPLE_CACHE";
}
```
---
## Service usage
```java
@Cacheable(value = CacheNames.SAMPLE_CACHE, key = "#id")
public SampleEntity findById(long id) { ... }
@CacheEvict(value = CacheNames.SAMPLE_CACHE, allEntries = true)
@Transactional
public void update(SampleEntity entity) { ... }
```
---
## application.yml
```yaml
humand:
:
cache:
enabled: true
ttl-minutes: 15
spring:
data:
redis:
host: ${SPRING_DATA_REDIS_HOST:localhost}
port: ${SPRING_DATA_REDIS_PORT:6379}
database: 0
timeout: 2s
connect-timeout: 2s
```
---
## application-test.yml
Disable Redis in tests so integration tests run without a Redis instance:
```yaml
humand:
:
cache:
enabled: false
spring:
autoconfigure:
exclude:
- org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration
- org.springframework.boot.data.redis.autoconfigure.DataRedisRepositoriesAutoConfiguration
```
Note the SB4 package path: `org.springframework.boot.data.redis.autoconfigure` (not `org.springframework.boot.autoconfigure.data.redis`).
---
## Infrastructure (Terraform)
SSM parameters (read from `/common/cache/`):
| SSM Path | Env Var |
|----------|---------|
| `/common/cache/hostname` | `SPRING_DATA_REDIS_HOST` |
| `/common/cache/port` | `SPRING_DATA_REDIS_PORT` |
| `/common/cache/password` | (secret, via SSM) |
Additional env vars in project module:
```hcl
{ name = "SPRING_DATA_REDIS_DATABASE", value = "0" }
{ name = "SPRING_DATA_REDIS_SSL_ENABLED", value = "true" }
```