Reputation: 1066
Recently I have been dabling in architecture, and I have a use-case where a very expensive computation from my domain is called very often with same parameters ( before you jump to any conclusions, I do not determine the parameters, and these are completely provided by external callers ). I would like to keep my application architecture as clean as possible and would not like to add a dependency on Spring in my domain layer, but I would still like to use Spring caching capabilities.
I am aware that Spring provides @Cacheable
annotation, but as said I do not want to use those on my classes to avoid adding a dependency on Spring.
Is it possible to do something like:
@Configuration
public MyConfigurationClass {
@Bean
public DomainClass createDomainClassBean() {
DomainClass domainInstance = new DomainClass(...);
// Programatically add @Cacheable annotation to the domain class.
...
}
}
Is it possible to enable @Cacheable
behavior for methods programatically, without relying on the annotation?
Edit: I am open to alternatives, which do not rely on Spring capabilities, but I would prefer avoiding adding dependencies to domain layer.
Upvotes: 2
Views: 3813
Reputation: 7981
Have a look at Spring's CacheProxyFactoryBean
class.
Internally, Spring's Cache Abstraction and caching infrastructure applied to Spring application service classes, your application domain classes, (whether using Declarative, Annotation-based Caching configuration and demarcation, or Declarative, XML-based Caching configuration, etc) is all backed by Spring AOP. After all, applying caching capabilities to application service components is a form of decoration.
The CacheProxyFactoryBean
accepts an array of CacheOperationSource
objects used to identify the type of cache operation(s) (e.g. GET/PUT, EVICT, etc; for example, the CacheableOperation for the @Cacheable
annotation) to perform on the proxy target's methods which are identified by an AOP Pointcut.
As you know, one source of caching configuration (metadata) for a cache enabled operation applied to (demarcating) your application service method is from an Annotation, like Spring's @Cacheable
annotation, not unlike how you'd use Spring's Transaction Management (with @Transactional
) or Spring Security.
Obviously, there are sources to parse (per) cache (operation) configuration from XML.
These are the infrastructure classes that Spring's caching infrastructure is essentially using under-the-hood when using Annotation or XML configuration to proxy your application service components and apply caching behavior.
You can manually set all of this up yourself (using Java-based configuration) to minimize the Spring footprint in your application classes, but that is quite a bit of boilerplate just to avoid Spring types in your application [service | DAO/Repository] classes when in fact Spring is already a dependency of your application.
It is somewhat akin to using JPA Annotations for application domain model classes (or entities), but that is in fact far worse given JPA Annotations are present in your domain "model" classes, IMO.
Alternatively, you could use XML (rather than Java-based configuration) or use JSR-107 Cache Annotations, which are supported by Spring as well.
Food for thought.
Upvotes: 2