Declaratively caching returned values of bean methods with Spring
I have a couple of beans defined with java @Configuration
. Some of them have methods perform pretty long calculations and I'd like to cache returned values for given arguments to avoid making those calculations every time a method is called.
Example:
@Configuration public class Config {
@Bean public CalculatorBean calcBean() {
return new CalculatorBean();
}
}
public class CalculatorBean {
public int hugeCalculation(int arg1, String arg2, double[] arg3) {
// ... very long calculation ...
}
}
Ideally, I'd like to annotate @Bean
methods in @Configur开发者_运维技巧ation
with some kind of custom @Cached(method="hugeCalculation", size=1000, ttl=36000)
and have bean factory automatically post-processed to wrap those beans in AOP proxies.
Are there any ready solutions of this kind? If not, what classes of Spring should I use to do this?
If the values really are constant, how about turning CalculatorBean
into a FactoryBean
instead? I'm not exactly sure how this would work with your @Configuration
-- I've never used that annotation.
You could return (for example) an Integer.class
, make it a singleton, and then do the calculations in the getObject
method. Something like the following:
public class CalculatorBean implements FactoryBean {
public Object getObject() {
return (Integer)hugeCalculation(...);
}
public Class getObjectType() {
return Integer.class;
}
public boolean isSingleton() {
return true;
}
private int hugeCalculation(int arg1, String arg2, double[] arg3) {
// ... very long calculation ...
}
}
In the end I ended up using Ehcache, but before that I created a following solution:
- I created a
BeanPostProcessor
that retrievedBeanDefinition
from the bean (doesn't matter before or after initialization). - From that
BeanDefinition
viagetSource()
I retrievedMethodMetadata
of the@Bean
-annotated method of that bean. - From that MethodMetadata I retrieved method's annotations.
- If they contained my custom
@Cached
annotation, I wrapped that bean in aMethodInterceptor
that cached method result in the way I needed.
Anyway, Ehcache is a better solution, and it has spring integration too, though it requires annotating actual methods that need to be cached. This means that you cannot cache calls selectively, but for most purposes it is not needed.
精彩评论