Spring Framework
  1. Spring Framework
  2. SPR-8696

Introduce qualifier in @Cacheable for cache manager name

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: 3.1 M2
    • Fix Version/s: 4.1 RC1
    • Component/s: Caching

      Description

      A qualifier attribute on @Cacheable would help to specify a CacheManager in the scenario described in the referenced forum post and summarized here:

      Two modules define their own CacheManager and use @Cacheable together with <cache:annotation-driven cache-manager="some_name"/> in their respective XML configuration files.

      When the XML configuration files from the two modules are used to build a single ApplicationContext, the second CacheManager is ignored as only one cache interceptor is registered by the namespace.

        Issue Links

          Activity

          Hide
          Stéphane Nicoll added a comment -

          If I understand you correctly, you mean keeping three attributes then: the name of the cache(s), the ref of the cacheManager and a ref to a CacheResolver implementation that would resolve the caches programmatically.

          The problem here is that I don't really see how it relates to your example. Specifying the cacheManager is exclusively used to resolve the specific cache name(s) against a different cache managers. I see it more has a third solution between @ActiveProfiles and ActiveProfilesResolver.

          If your point is that users wants to be able to manage different cache managers only declaratively, then yes, it makes sense to keep the 3 attributes.

          Setting at the class level is already implemented and pending review (but I asked some delay on the review as the work on JSR-107 is slightly changing things there).

          Thanks for the feedback Sam!

          Show
          Stéphane Nicoll added a comment - If I understand you correctly, you mean keeping three attributes then: the name of the cache(s), the ref of the cacheManager and a ref to a CacheResolver implementation that would resolve the caches programmatically. The problem here is that I don't really see how it relates to your example. Specifying the cacheManager is exclusively used to resolve the specific cache name(s) against a different cache managers. I see it more has a third solution between @ActiveProfiles and ActiveProfilesResolver . If your point is that users wants to be able to manage different cache managers only declaratively, then yes, it makes sense to keep the 3 attributes. Setting at the class level is already implemented and pending review (but I asked some delay on the review as the work on JSR-107 is slightly changing things there). Thanks for the feedback Sam!
          Hide
          Sam Brannen added a comment - - edited

          With regard to @ActiveProfiles, that annotation is used on a test class, and the test instance is not a bean in an ApplicationContext, so a static declaration via profiles is the best we can offer other than the programmatic approach of a custom ActiveProfilesResolver.

          However, in the case of caching, each annotated class is actually a bean in the ApplicationContext. So I'm wondering if it wouldn't make sense to evaluate the value attributes of @Cacheable, @CachePut, and @CacheEvict as SpEL expressions. That would enable developers to make programmatic, run-time decisions for which cache to use. This would essentially remove the need for an explicit CacheResolver API in Spring, since the SpEL expression could delegate to a bean in the context for this purpose (which may happen to implement a CacheResolver but wouldn't necessarily have to due to the dynamic method invocation nature of SpEL expressions).

          And if you introduce a cacheManager attribute in @Cacheable, @CachePut, and @CacheEvict, I would also recommend that it simply be a String that can be evaluated as a SpEL expression, the result of which is the name of the cache manager bean to use. Like in the paragraph above, using a SpEL expression would avoid the need for any kind of special cache manager resolver API.

          Show
          Sam Brannen added a comment - - edited With regard to @ActiveProfiles , that annotation is used on a test class, and the test instance is not a bean in an ApplicationContext , so a static declaration via profiles is the best we can offer other than the programmatic approach of a custom ActiveProfilesResolver . However, in the case of caching, each annotated class is actually a bean in the ApplicationContext . So I'm wondering if it wouldn't make sense to evaluate the value attributes of @Cacheable , @CachePut , and @CacheEvict as SpEL expressions. That would enable developers to make programmatic, run-time decisions for which cache to use. This would essentially remove the need for an explicit CacheResolver API in Spring, since the SpEL expression could delegate to a bean in the context for this purpose (which may happen to implement a CacheResolver but wouldn't necessarily have to due to the dynamic method invocation nature of SpEL expressions). And if you introduce a cacheManager attribute in @Cacheable , @CachePut , and @CacheEvict , I would also recommend that it simply be a String that can be evaluated as a SpEL expression, the result of which is the name of the cache manager bean to use. Like in the paragraph above, using a SpEL expression would avoid the need for any kind of special cache manager resolver API.
          Hide
          Sam Brannen added a comment -

          If your point is that users wants to be able to manage different cache managers only declaratively, then yes, it makes sense to keep the 3 attributes.

          Evaluating those attributes as SpEL expressions basically kills two birds with one stone. Whether or not we introduce dedicated resolver APIs is a different question.

          My main point in my original comment was that it is often a good idea to provide both a declarative and a programmatic mechanism for configuring such features, and these mechanisms should be available at the class-level as well as at the method-level, whereby method-level configuration overrides class-level configuration.

          Furthermore, any defaults configured via the XML namespace or @Enable annotation should be overridable via annotations at the class-level and method-level.

          So in the end you have three locations for declaring configuration for the cache manager, cache name resolution, and cache key generation. And this constellation represents a hierarchy like this:

          1. XML namespace or @Enable annotation
          2. Class-level within an annotated component
          3. Method-level within an annotated component

          Lower levels of configuration override higher levels.

          Regards,

          Sam

          Show
          Sam Brannen added a comment - If your point is that users wants to be able to manage different cache managers only declaratively, then yes, it makes sense to keep the 3 attributes. Evaluating those attributes as SpEL expressions basically kills two birds with one stone . Whether or not we introduce dedicated resolver APIs is a different question. My main point in my original comment was that it is often a good idea to provide both a declarative and a programmatic mechanism for configuring such features, and these mechanisms should be available at the class-level as well as at the method-level, whereby method-level configuration overrides class-level configuration. Furthermore, any defaults configured via the XML namespace or @Enable annotation should be overridable via annotations at the class-level and method-level. So in the end you have three locations for declaring configuration for the cache manager, cache name resolution, and cache key generation. And this constellation represents a hierarchy like this: XML namespace or @Enable annotation Class-level within an annotated component Method-level within an annotated component Lower levels of configuration override higher levels. Regards, Sam
          Hide
          Stéphane Nicoll added a comment -

          Sam, please see SPR-11490 for the programmatic mechanism.

          Thanks!

          Show
          Stéphane Nicoll added a comment - Sam, please see SPR-11490 for the programmatic mechanism. Thanks!
          Hide
          Stéphane Nicoll added a comment -

          It is now possible to specify the CacheManager to use per operation. The related cache annotation now has an extra attribute that defines the name of the CacheManager bean to use. The cache manager that was previously used is therefore a 'default' cache manager (i.e. the one to use if no custom cache manager has been set on the operation).

          Show
          Stéphane Nicoll added a comment - It is now possible to specify the CacheManager to use per operation. The related cache annotation now has an extra attribute that defines the name of the CacheManager bean to use. The cache manager that was previously used is therefore a 'default' cache manager (i.e. the one to use if no custom cache manager has been set on the operation).

            People

            • Assignee:
              Stéphane Nicoll
              Reporter:
              Gaetan Pitteloud
              Last updater:
              Stéphane Nicoll
            • Votes:
              10 Vote for this issue
              Watchers:
              12 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                3 weeks, 2 days ago