From 0690b58878f0e6c57a443720244049b16ba3cfd5 Mon Sep 17 00:00:00 2001 From: Stevo Slavic Date: Thu, 16 Feb 2012 14:40:27 +0100 Subject: [PATCH] Predict specific object type in EhCacheFactoryBean Prior to this change, before a bean is created by EhCacheFactoryBean, its #getObjectType would return only an Ehcache interface. This caused unwanted wiring issues as described in the related JIRA issue. This fix makes use of EhCacheFactoryBean's configuration to determine the specific Ehcache object type even before it's created, such that the container is provided with as much information as possible when resolving dependencies. Nevertheless, users are advised to code to the Ehcache interface. Issue: SPR-7843 --- .../cache/ehcache/EhCacheFactoryBean.java | 24 +++++++++++++++++-- .../cache/ehcache/EhCacheSupportTests.java | 11 +++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java b/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java index 745742eca3..2376a5c9d5 100644 --- a/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/cache/ehcache/EhCacheFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory; import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache; import net.sf.ehcache.event.CacheEventListener; import net.sf.ehcache.store.MemoryStoreEvictionPolicy; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -398,8 +399,27 @@ public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, return this.cache; } + /** + * Predict the particular {@code Ehcache} implementation that will be returned from + * {@link #getObject()} based on logic in {@link #createCache()} and + * {@link #decorateCache(Ehcache)} as orchestrated by {@link #afterPropertiesSet()}. + */ public Class getObjectType() { - return (this.cache != null ? this.cache.getClass() : Ehcache.class); + if (this.cache != null) { + return this.cache.getClass(); + } + if (this.cacheEntryFactory != null) { + if (this.cacheEntryFactory instanceof UpdatingCacheEntryFactory) { + return UpdatingSelfPopulatingCache.class; + } + else { + return SelfPopulatingCache.class; + } + } + if (this.blocking) { + return BlockingCache.class; + } + return Cache.class; } public boolean isSingleton() { diff --git a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java b/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java index 2d9b59d0ad..b8f4c01b3c 100644 --- a/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java +++ b/spring-context/src/test/java/org/springframework/cache/ehcache/EhCacheSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.cache.ehcache; import junit.framework.TestCase; + import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Ehcache; @@ -82,7 +83,8 @@ public class EhCacheSupportTests extends TestCase { EhCacheManagerFactoryBean cacheManagerFb = null; try { EhCacheFactoryBean cacheFb = new EhCacheFactoryBean(); - assertEquals(Ehcache.class, cacheFb.getObjectType()); + Class objectType = cacheFb.getObjectType(); + assertTrue(Ehcache.class.isAssignableFrom(objectType)); assertTrue("Singleton property", cacheFb.isSingleton()); if (useCacheManagerFb) { cacheManagerFb = new EhCacheManagerFactoryBean(); @@ -94,6 +96,8 @@ public class EhCacheSupportTests extends TestCase { cacheFb.setCacheName("myCache1"); cacheFb.afterPropertiesSet(); cache = (Cache) cacheFb.getObject(); + Class objectType2 = cacheFb.getObjectType(); + assertSame(objectType, objectType2); CacheConfiguration config = cache.getCacheConfiguration(); assertEquals("myCache1", cache.getName()); if (useCacheManagerFb){ @@ -166,6 +170,7 @@ public class EhCacheSupportTests extends TestCase { cacheFb.setCacheManager(cm); cacheFb.setCacheName("myCache1"); cacheFb.setBlocking(true); + assertEquals(cacheFb.getObjectType(), BlockingCache.class); cacheFb.afterPropertiesSet(); Ehcache myCache1 = cm.getEhcache("myCache1"); assertTrue(myCache1 instanceof BlockingCache); @@ -188,6 +193,7 @@ public class EhCacheSupportTests extends TestCase { return key; } }); + assertEquals(cacheFb.getObjectType(), SelfPopulatingCache.class); cacheFb.afterPropertiesSet(); Ehcache myCache1 = cm.getEhcache("myCache1"); assertTrue(myCache1 instanceof SelfPopulatingCache); @@ -213,6 +219,7 @@ public class EhCacheSupportTests extends TestCase { public void updateEntryValue(Object key, Object value) throws Exception { } }); + assertEquals(cacheFb.getObjectType(), UpdatingSelfPopulatingCache.class); cacheFb.afterPropertiesSet(); Ehcache myCache1 = cm.getEhcache("myCache1"); assertTrue(myCache1 instanceof UpdatingSelfPopulatingCache);