Skip to content

Configuration Reference

This page covers all configuration options available in CoCache, from annotation parameters to Spring Boot properties and custom bean overrides.

@CoCache Annotation

The @CoCache annotation marks a cache interface for proxy-based implementation. It configures the distributed cache layer behavior.

ParameterTypeDefaultDescriptionSource
nameString"" (interface name)Cache name used for event matching and bean namingCoCache.kt:30
keyPrefixString""Prefix prepended to all cache keys in the distributed layerCoCache.kt:31
keyExpressionString""SpEL expression for key derivationCoCache.kt:33
ttlLongLong.MAX_VALUETime-to-live in the unit specified by the cache implementation (seconds for Redis)CoCache.kt:35
ttlAmplitudeLong10Random jitter range added/subtracted from TTL to prevent cache avalancheCoCache.kt:36

TTL Jitter Mechanism

The ttlAmplitude parameter prevents cache avalanche (many keys expiring simultaneously) by randomizing the actual TTL:

actualTtl = ttl + random(-ttlAmplitude, +ttlAmplitude)
mermaid
graph LR
    subgraph ttl_jitter ["TTL Jitter"]
        direction LR
        TTL["ttl = 120s"]
        Amp["ttlAmplitude = 10"]
        Result["actualTtl = 110..130s<br>(random)"]
    end

    TTL --> Result
    Amp --> Result

    style TTL fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style Amp fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style Result fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

Source: ComputedTtlAt.kt:49-56

Example

kotlin
@CoCache(keyPrefix = "user:", ttl = 120, ttlAmplitude = 10)
interface UserCache : Cache<String, User>

@GuavaCache Annotation

Configures a Guava-based ClientSideCache (L2 local cache).

ParameterTypeDefaultDescriptionSource
initialCapacityInt-1 (unset)Initial capacity of the Guava cacheGuavaCache.kt:30
concurrencyLevelInt-1 (unset)Number of concurrent updates the cache can handleGuavaCache.kt:31
maximumSizeLong-1 (unset)Maximum number of entries the cache may holdGuavaCache.kt:32
expireUnitTimeUnitTimeUnit.SECONDSTime unit for expireAfterWrite and expireAfterAccessGuavaCache.kt:33
expireAfterWriteLong-1 (unset)Duration after write before entry expiresGuavaCache.kt:34
expireAfterAccessLong-1 (unset)Duration after last access before entry expiresGuavaCache.kt:35

@CaffeineCache Annotation

Configures a Caffeine-based ClientSideCache (L2 local cache).

ParameterTypeDefaultDescriptionSource
initialCapacityInt-1 (unset)Initial capacity of the Caffeine cacheCaffeineCache.kt:31
maximumSizeLong-1 (unset)Maximum number of entries the cache may holdCaffeineCache.kt:32
expireUnitTimeUnitTimeUnit.SECONDSTime unit for expiration settingsCaffeineCache.kt:33
expireAfterWriteLong-1 (unset)Duration after write before entry expiresCaffeineCache.kt:34
expireAfterAccessLong-1 (unset)Duration after last access before entry expiresCaffeineCache.kt:35

@JoinCacheable Annotation

Marks a cache interface as a JoinCache that composes two cached values.

ParameterTypeDefaultDescriptionSource
firstCacheNameString""Name of the primary cache to retrieve the first valueJoinCacheable.kt
joinCacheNameString""Name of the secondary cache to retrieve the joined valueJoinCacheable.kt
joinKeyExpressionString""SpEL expression to extract the join key from the first valueJoinCacheable.kt
kotlin
@JoinCacheable(
    firstCacheName = "UserExtendInfoCache",
    joinCacheName = "UserCache",
    joinKeyExpression = "#{#root.userId}"
)
interface UserExtendInfoJoinCache : JoinCache<String, UserExtendInfo, String, User>

Source: cocache-example/.../cache/UserExtendInfoJoinCache.kt

Spring Boot Properties

CoCacheProperties

PropertyTypeDefaultDescriptionSource
cocache.enabledBooleantrueEnables or disables the entire CoCache auto-configurationCoCacheProperties.kt
yaml
# application.yml
cocache:
  enabled: true

When cocache.enabled is false, all CoCache beans are skipped. The conditional is handled by @ConditionalOnCoCacheEnabled.

Source: ConditionalOnCoCacheEnabled.kt

Auto-Configuration Bean Registry

The CoCacheAutoConfiguration class registers all required beans. Every bean uses @ConditionalOnMissingBean, meaning you can override any bean by declaring your own.

mermaid
graph TB
    subgraph autoconfig ["CoCacheAutoConfiguration"]
        direction TB
        ClientId["ClientIdGenerator<br>@ConditionalOnMissingBean"]
        CacheFact["CacheFactory<br>@ConditionalOnMissingBean"]
        CoCacheMgr["CoCacheManager"]
        RedisContainer["RedisMessageListenerContainer<br>@ConditionalOnMissingBean"]
        EventBus["CacheEvictedEventBus<br>RedisCacheEvictedEventBus"]
        CoherentFact["CoherentCacheFactory<br>@ConditionalOnMissingBean"]
        CacheSrcFact["CacheSourceFactory<br>@ConditionalOnMissingBean"]
        CSCFact["ClientSideCacheFactory<br>@ConditionalOnMissingBean"]
        DistFact["DistributedCacheFactory<br>@ConditionalOnMissingBean"]
        KeyConvFact["KeyConverterFactory<br>@ConditionalOnMissingBean"]
        ProxyFact["CacheProxyFactory<br>@ConditionalOnMissingBean"]
        JoinKeyFact["JoinKeyExtractorFactory<br>@ConditionalOnMissingBean"]
        JoinProxyFact["JoinCacheProxyFactory<br>@ConditionalOnMissingBean"]
    end

    RedisContainer --> EventBus
    EventBus --> CoherentFact
    CoherentFact --> ProxyFact
    CSCFact --> ProxyFact
    DistFact --> ProxyFact
    CacheSrcFact --> ProxyFact
    KeyConvFact --> ProxyFact
    ClientId --> ProxyFact
    CacheFact --> JoinProxyFact
    JoinKeyFact --> JoinProxyFact

    style ClientId fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CacheFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CoCacheMgr fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style RedisContainer fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style EventBus fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CoherentFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CacheSrcFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CSCFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style DistFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style KeyConvFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style ProxyFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style JoinKeyFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style JoinProxyFact fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

Source: CoCacheAutoConfiguration.kt:61-186

Auto-Configured Beans Reference

BeanTypeConditionalDescription
defaultHostClientIdGeneratorClientIdGenerator@ConditionalOnMissingBeanGenerates client IDs based on host address
cacheFactoryCacheFactory@ConditionalOnMissingBeanResolves cache instances from the bean factory
coCacheManagerCoCacheManager--Integrates with Spring Cache abstraction
cocacheRedisMessageListenerContainerRedisMessageListenerContainer@ConditionalOnMissingBean + @ConditionalOnSingleCandidateListens for Redis pub/sub messages
cacheEvictedEventBusCacheEvictedEventBus@ConditionalOnMissingBeanPublishes and subscribes to cache eviction events via Redis
coherentCacheFactoryCoherentCacheFactory@ConditionalOnMissingBeanCreates DefaultCoherentCache instances
cacheSourceFactoryCacheSourceFactory@ConditionalOnMissingBeanResolves CacheSource beans by name
clientSideCacheFactoryClientSideCacheFactory@ConditionalOnMissingBeanCreates ClientSideCache instances from annotations
distributedCacheFactoryDistributedCacheFactory@ConditionalOnMissingBeanCreates RedisDistributedCache instances
keyConverterFactoryKeyConverterFactory@ConditionalOnMissingBeanConverts cache keys using SpEL expressions
cacheProxyFactoryCacheProxyFactory@ConditionalOnMissingBeanCreates proxy implementations of cache interfaces
joinKeyExtractorFactoryJoinKeyExtractorFactory@ConditionalOnMissingBeanResolves join key extractors from SpEL expressions
joinCacheProxyFactoryJoinCacheProxyFactory@ConditionalOnMissingBeanCreates proxy implementations of JoinCache interfaces

Custom Bean Overrides

Custom ClientSideCache

Override the L2 cache for a specific cache interface by declaring a bean:

kotlin
@Configuration
class UserCacheConfiguration {
    @Bean
    fun customizeUserClientSideCache(): ClientSideCache<User> {
        return MapClientSideCache(ttl = 120, ttlAmplitude = 10)
    }
}

The auto-configuration uses SpringClientSideCacheFactory which resolves beans from the Spring BeanFactory. If a matching ClientSideCache bean exists, it takes precedence over annotation-based Guava/Caffeine defaults.

Custom CacheSource

Provide a data source loader for a specific cache:

kotlin
@Configuration
class UserCacheConfiguration {
    @Bean
    fun customizeUserCacheSource(): CacheSource<String, User> {
        return object : CacheSource<String, User> {
            override fun loadCacheValue(key: String): CacheValue<User>? {
                // Load from database
                return database.findById(key)?.let {
                    DefaultCacheValue.forever(it)
                }
            }
        }
    }
}

If no CacheSource bean is provided, the cache uses CacheSource.noOp() which always returns null.

Custom DistributedCache

Override the distributed cache implementation:

kotlin
@Bean
fun customDistributedCache(redisTemplate: StringRedisTemplate): DistributedCache<User> {
    val codec = ObjectToJsonCodecExecutor<User>(
        User::class.java, redisTemplate, ObjectMapper()
    )
    return RedisDistributedCache(redisTemplate, codec)
}

Custom CacheEvictedEventBus

Replace the Redis-based event bus with a custom implementation:

kotlin
@Bean
fun customEventBus(): CacheEvictedEventBus {
    // Custom event bus (e.g., Kafka, RabbitMQ)
    return MyCustomEventBus()
}

Configuration Flow

mermaid
sequenceDiagram
autonumber
    participant App as Spring Boot
    participant Auto as CoCacheAutoConfiguration
    participant Prop as CoCacheProperties
    participant Bean as BeanFactory
    participant Proxy as CacheProxyFactory

    App->>Prop: bind cocache.enabled
    Prop-->>Auto: enabled = true
    Auto->>Auto: register default beans
    Auto->>Bean: register ClientIdGenerator
    Auto->>Bean: register CacheFactory
    Auto->>Bean: register CacheEvictedEventBus
    Auto->>Bean: register CoherentCacheFactory
    Auto->>Bean: register CacheProxyFactory
    App->>Proxy: @EnableCoCache(caches = [...])
    Proxy->>Bean: resolve ClientSideCache (custom or default)
    Proxy->>Bean: resolve CacheSource (custom or noop)
    Proxy->>Proxy: create CoherentCacheConfiguration
    Proxy->>Proxy: create DefaultCoherentCache
    Proxy->>Proxy: create JDK Proxy for interface

CosID Integration

When the CosID library is on the classpath and a HostAddressSupplier bean is present, the auto-configuration registers a HostClientIdGenerator that uses CosID's host address for client ID generation.

kotlin
@Configuration
@ConditionalOnClass(HostAddressSupplier::class)
class CosIdHostAddressSupplierAutoConfiguration {
    @Bean
    @ConditionalOnBean(HostAddressSupplier::class)
    fun inetUtilsHostClientIdGenerator(
        hostAddressSupplier: HostAddressSupplier
    ): ClientIdGenerator {
        return HostClientIdGenerator {
            hostAddressSupplier.hostAddress
        }
    }
}

Source: CoCacheAutoConfiguration.kt:175-185

Released under the Apache License 2.0.