diff --git a/CacheGrailsPlugin.groovy b/CacheGrailsPlugin.groovy index 646b7891..84e28ef1 100644 --- a/CacheGrailsPlugin.groovy +++ b/CacheGrailsPlugin.groovy @@ -126,6 +126,7 @@ class CacheGrailsPlugin { 'proxy-target-class': proxyTargetClass) // updates the AnnotationCacheOperationSource with a custom subclass + // and adds the 'cacheOperationSource' alias cacheBeanPostProcessor(CacheBeanPostProcessor) grailsCacheManager(GrailsConcurrentMapCacheManager) @@ -138,8 +139,7 @@ class CacheGrailsPlugin { grailsCacheFilter(MemoryPageFragmentCachingFilter) { cacheManager = ref('grailsCacheManager') - // TODO this name might be brittle - perhaps do by type? - cacheOperationSource = ref(GrailsAnnotationCacheOperationSource.BEAN_NAME) + cacheOperationSource = ref('cacheOperationSource') keyGenerator = ref('webCacheKeyGenerator') expressionEvaluator = ref('webExpressionEvaluator') } @@ -155,22 +155,21 @@ class CacheGrailsPlugin { def onChange = { event -> - if (!isEnabled(event.application)) { + def application = event.application + if (!isEnabled(application)) { return } - if (!event.source) { + def source = event.source + if (!source) { return } - if (event.application.isControllerClass(event.source) || - event.application.isServiceClass(event.source)) { - - def annotationCacheOperationSource = event.ctx.getBean(GrailsAnnotationCacheOperationSource.BEAN_NAME) - annotationCacheOperationSource.reset() + if (application.isControllerClass(source) || application.isServiceClass(source)) { + event.ctx.cacheOperationSource.reset() log.debug 'Reset GrailsAnnotationCacheOperationSource cache' } - else if (event.application.isCacheConfigClass(event.source)) { + else if (application.isCacheConfigClass(source)) { reloadCaches event.ctx } } diff --git a/src/java/grails/plugin/cache/CacheBeanPostProcessor.java b/src/java/grails/plugin/cache/CacheBeanPostProcessor.java index 8d2d9f46..0ede07de 100644 --- a/src/java/grails/plugin/cache/CacheBeanPostProcessor.java +++ b/src/java/grails/plugin/cache/CacheBeanPostProcessor.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.cache.annotation.AnnotationCacheOperationSource; /** * Changes the bean class of the org.springframework.cache.annotation.AnnotationCacheOperationSource#0 @@ -37,8 +38,11 @@ public class CacheBeanPostProcessor implements BeanDefinitionRegistryPostProcess public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { log.info("postProcessBeanDefinitionRegistry start"); - AbstractBeanDefinition beanDef = (AbstractBeanDefinition)registry.getBeanDefinition( - GrailsAnnotationCacheOperationSource.BEAN_NAME); + AbstractBeanDefinition beanDef = findBeanDefinition(registry); + if (beanDef == null) { + log.error("Unable to find the AnnotationCacheOperationSource bean definition"); + return; + } // change the class to the plugin's subclass beanDef.setBeanClass(GrailsAnnotationCacheOperationSource.class); @@ -54,7 +58,38 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { log.debug("updated {}", beanDef); } - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + protected AbstractBeanDefinition findBeanDefinition(BeanDefinitionRegistry registry) { + + AbstractBeanDefinition beanDef = null; + String beanName = null; + + if (registry.containsBeanDefinition(GrailsAnnotationCacheOperationSource.BEAN_NAME)) { + beanDef = (AbstractBeanDefinition)registry.getBeanDefinition( + GrailsAnnotationCacheOperationSource.BEAN_NAME); + beanName = GrailsAnnotationCacheOperationSource.BEAN_NAME; + } + else { + String className = AnnotationCacheOperationSource.class.getName(); + for (String name : registry.getBeanDefinitionNames()) { + if (className.equals(registry.getBeanDefinition(name).getBeanClassName())) { + beanDef = (AbstractBeanDefinition)registry.getBeanDefinition(name); + beanName = name; + break; + } + } + } + + if (beanDef != null) { + // make it easier to work with + if (!"cacheOperationSource".equals(beanName)) { + registry.registerAlias(beanName, "cacheOperationSource"); + } + } + + return beanDef; + } + + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { log.info("postProcessBeanFactory"); } }