You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spring's Caching Configuration through properties is incredibly useful. For my in particular I enjoy the ability to set it to none in my tests and have it just disable all caching. However the moment you want two CacheManagers you lose out on this ability.
I'll use an example situation where the Developer wants to have two caches. A local Caffeine Cache and a Distributed Redis Cache. Since the declaration of any Cache Manager disables auto configuration, a simple setup requires the following.
You could still leverage the CacheProperties for configuring everything but the Cache Names. However this approach isn't recommended (Properties Classes can change), and also removes a lot of quality of life changes from AutoConfiguration (Namely being able to disable it within Tests).
As most Developers will be using Unique Cache Names between their Caches, the following change seems reasonable to me.
spring:
cache:
type: composite # Added to the Type Enum.cache-names: #Can be kept, however isn't used for type==Compositeredis:
cache-names: my-redis-cache # Used when type==Composite, unsure how it would be used otherwise# Other configurationcaffeine:
cache-names: my-caffeine-cache # See notes on Redis Cache Configuration# Other Configurationcomposite:
using: # Controls the other Types configured when type==composite
- redis
- caffeinenoop-fallback: false # This is the only property in `CompositeCacheManager`, so we allow it to be configured
When spring.cache.type=composite, the following are enforced to ensure deterministic caching behavior.
All CacheManager instances being used are automatically configured to disable Lazy Cache Creation. This is so that only the CacheManager with the Cache Name provided is used.
Cache Names across all configured CacheManagers in spring.cache.composite.using are unique to the CacheManager*, so the following is invalid.
Since the above cannot resolve to a single CacheManager, the following annotation wouldn't behave deterministically.
@Cacheable("my-cache")
*This behavior could potentially be tied to if a CacheResolver bean is provided.
As you can select the CacheManager instance directly in @Cacheable, the qualifier String would be {cacheType}CacheManager, for example redisCacheManager or caffeineCacheManager. With the CompositeCacheManager using the traditional cacheManager
Current alternatives,
You can declare two CacheManagers beans with a Primary one, then utilize @Cacheable(cacheManager="my-manager"), instead of the CompositeCacheManager. However changing the location of a single Cache to a different Manager will have cascading code changes.
You can manually build the CompositeCacheManager, however you'll lose out on Auto Configuration.
The text was updated successfully, but these errors were encountered:
Thanks for the suggestion but I've already shared our position in the previous issue you've raised on this topic. Spring Boot auto-configuration will not auto-configure multiple beans of the same type until we review #15732.
Irrespective of this, your proposal sounds like programming by properties, which we usually don't recommend. Working on the above would make the auto-configuration much more complex and it already is at the moment.
I misunderstood #15732 a bit then. I read it as specifically covering specifically DataSource beans, and how it can be hard to coordinate which one to use.
I do think there is value in discussing the CompositeCacheManager some more though. It is a useful implementation that currently has no visibility to the average Spring Developer.
I misunderstood #15732 a bit then. I read it as specifically covering specifically DataSource beans, and how it can be hard to coordinate which one to use.
Did you read the complete history? Specifically this comment.
I do think there is value in discussing the CompositeCacheManager some more though. It is a useful implementation that currently has no visibility to the average Spring Developer.
I'd argue the average developer wouldn't use such a thing. Any implementation that we put out there has to be reasonable in terms of complexity. Your idea of using qualifier Strings is absolutely reasonable for a private implementation because you chose and live with your conventions, but not here.
Spring's Caching Configuration through properties is incredibly useful. For my in particular I enjoy the ability to set it to
none
in my tests and have it just disable all caching. However the moment you want twoCacheManager
s you lose out on this ability.I'll use an example situation where the Developer wants to have two caches. A local Caffeine Cache and a Distributed Redis Cache. Since the declaration of any Cache Manager disables auto configuration, a simple setup requires the following.
You could still leverage the
CacheProperties
for configuring everything but the Cache Names. However this approach isn't recommended (Properties Classes can change), and also removes a lot of quality of life changes from AutoConfiguration (Namely being able to disable it within Tests).As most Developers will be using Unique Cache Names between their Caches, the following change seems reasonable to me.
When
spring.cache.type=composite
, the following are enforced to ensure deterministic caching behavior.All
CacheManager
instances being used are automatically configured to disable Lazy Cache Creation. This is so that only theCacheManager
with the Cache Name provided is used.Cache Names across all configured
CacheManager
s inspring.cache.composite.using
are unique to theCacheManager
*, so the following is invalid.Since the above cannot resolve to a single
CacheManager
, the following annotation wouldn't behave deterministically.*This behavior could potentially be tied to if a
CacheResolver
bean is provided.As you can select the
CacheManager
instance directly in@Cacheable
, the qualifier String would be{cacheType}CacheManager
, for exampleredisCacheManager
orcaffeineCacheManager
. With theCompositeCacheManager
using the traditionalcacheManager
Current alternatives,
You can declare two
CacheManager
s beans with a Primary one, then utilize@Cacheable(cacheManager="my-manager")
, instead of theCompositeCacheManager
. However changing the location of a single Cache to a different Manager will have cascading code changes.You can manually build the
CompositeCacheManager
, however you'll lose out on Auto Configuration.The text was updated successfully, but these errors were encountered: