-
Notifications
You must be signed in to change notification settings - Fork 41.2k
JCache CacheManager customization should happen before named caches are created #32993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
FTR, I uncovered this limitation when I was trying to "customize" the JCache
Which is the same issue that the user had in Issue #15359. My circular dependency involved: JCache CacheManager I then took a different approach to properly address this circular dependency when I then realized that the "customization" would not work in any case, given the description of the limitation above. |
NOTE: My cyclic dependency was even nicely demonstrated by Spring Boot...
|
@jxblum Have you got a sample project that shows what you're trying to do? I'm not sure I totally understand all of the moving parts. I don't think that we can change the |
@philwebb - Happy to discuss my UC more offline (will reach out to you directly). It is a bit complex to explain here as well as confidential ATM. |
There's quite a back and forth, but this PR has some background as why we're doing things this way: #28498 Besides back compatibility, I am not sure we should change that. And if we do we might just as well introduce more options to configure cache names from properties, or remove the cache names property altogether, or make it cache provider specific. |
In all fairness, and after thinking about this a bit more, I suppose it is also possible to delay the JCache Of course, I don't recall precisely when Framework (or perhaps Boot in this case) would call |
@snicoll - My UC, and many UCs for that matter, has less to do with creating caches up front (using the I simply used this property to conveniently create caches for the underlying caching providers in a somewhat generic manner since I am testing my prototype across multiple caching providers. All I will say is, when it comes to "consistency", then it is crucial that any system/application architectural component that acquires a handle to a |
@snicoll - After a quick glance and brief review of #28498 (a quite lengthy thread of interactions), I fail to see how customizing the JCache In fact, I'd argue whether it is even advisable to create Not all caching providers are equal, not by far. Some, like Hazelcast, GridGain, GemFire/Geode, etc, depending on the "named" cache, may perform a very expensive Get Initial Image (GII), that could (block and) delay startup of the Spring Boot application (or minimally make the "named" cache unavailable, particularly in premature So, I lean towards, as you say, "...or make it cache provider specific", TBH.
|
FYI, and 1 final thing to note here, I have explored several alternative approaches to my UC/prototype/POC; One that I already have is a working implementation based on direct customization of Spring's I explored Spring Boot's extension points because of the ability to "customize" not only Spring Caching infra components (i.e. using Unfortunately, even the JSR-107 JCache SPI provides no such opportunities for extensions/plugins, which makes Spring Boot's customization offering very attractive and welcomed... needless to say, a really nice and useful feature! I even explored directly adapting the underlying caching provider's actual cache implementation, but in the end having a standard like the JCache API makes the solution more universally portable. Truthfully, it is a balancing act between finding the right level of abstraction (e.g. Spring's Cache Abstraction vs. the JCache API, both covering a wide array of caching providers) and getting too low-level, such as with Hazelcast and Distributed Map instances and |
I think there is a reason why there's isn't such extension point in the JCache API. Reading all of that, I am not quite sure I fully understood what you're trying to do, or why the current arrangement is not valid. As Phil asked, please share a small sample that reproduces the scenario you've described. It shouldn't be your current project as we'd like to focus on the ask without dealing with the specifics of your project. |
In a nutshell, and to be a bit more concrete, my UC would be equivalent to (which is completely possible with JCache alone, it is just more "manual" work that is inconvenient compared with Spring Boot's auto-configuration arrangement): Given: class CustomCachingProvider implements javax.caching.spi.CachingProvider { ... } Or (simply just, possible with Spring Boot): class CustomCacheManager implements javax.cache.CacheManager { ... } Then (here): CachingProvider cachingProvider = Caching.getCachingProvider();
CustomCachingProvider customCachingProvider =
CustomCachingProvider.wrap(cachingProvider, [<other essential dependencies>]); Or (here): CachingProvider cachingProvider = Caching.getCachingProvider(cachingProviderFqn);
"" "" As you can imagine, then anything returned by the custom/wrapped In other words (and for instance): class CustomCacheManager implements javax.cache.CacheManager {
// impl similar for getCache(String, Class<K>, Class<V>)
public CacheManager getCache(String name) {
return CustomCache.wrap(wrappedCacheManager.getCache(name),
[<passing along other essential dependencies>]);
}
...
} And, then: class CustomCache implements javax.cache.Cache {
public Object get(Object key) {
// pre-processing
Object value = wrappedCache.get(key);
// post-processing (potentially modifying value)
return value;
}
} Fortunately, and unlike other libraries or frameworks (e.g. Hibernate) integrating with JCache, Spring Boot nicely provides a means to at least customize the JCache I just need the JCache I am not at the liberty to talk specifics, but can share an example (test) if this would help. |
That's what we're asking (a small sample we can run ourselves). So, yes please. |
I am back at a keyboard and had a chance to review this a bit more. I don't think we should be exposing a high-level contract to wrap a Applying such customizations should only happen on the auto-configured |
Uh oh!
There was an error while loading. Please reload this page.
Currently, Spring Boot auto-configuration applies customization to the JCache
CacheManager
after the creation of (any) configured, "named" caches declared with thespring.cache.cache-names
property in Spring Boot application.properties.If the Spring Boot
CacheManagerCustomizer(s)
for the JCacheCacheManager
were to wrap ("decorate") the underlying JCache caching provider'sCacheManager
implementation (for example: Hazelcast) so that instances of JCacheCaches
created with the custom wrapped/decoratedCacheManager
usingCacheManager.createCache(..)
could also be wrapped and decorated as well, and most likely the case, then the current order for customization vs. cache creation in Spring Boot does not currently allow this to happen.This order of customization is in contrast to the inverse behavior of Spring Boot's auto-configuration that applies customization to Spring's own
CacheManager
(Adapter) implementation for the underlying JCacheCacheManager
created/customized in the dependent bean definition as seen in the SpringCacheManager
bean definition.By applying customization to the Spring
JCacheCacheManager
immediately after creation, this ensures that the SpringCacheManager
will be customized before any SpringCaches
are created.I'd also argue that there do exist cases where wrapping the JCache
CacheManager
implementation (rather than Spring'sCacheManager
implementation) is advantageous and even necessary, since other libraries or frameworks (e.g. Hibernate) also depend on caching, and do so using the JCache API.The text was updated successfully, but these errors were encountered: