KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > cache > ehcache > EhCacheFactoryBean


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.cache.ehcache;
18
19 import java.io.IOException JavaDoc;
20
21 import net.sf.ehcache.Cache;
22 import net.sf.ehcache.CacheException;
23 import net.sf.ehcache.CacheManager;
24 import net.sf.ehcache.Ehcache;
25 import net.sf.ehcache.constructs.blocking.BlockingCache;
26 import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
27 import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
28 import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory;
29 import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache;
30 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import org.springframework.beans.factory.BeanNameAware;
35 import org.springframework.beans.factory.FactoryBean;
36 import org.springframework.beans.factory.InitializingBean;
37 import org.springframework.util.Assert;
38
39 /**
40  * FactoryBean that creates a named EHCache {@link net.sf.ehcache.Cache} instance
41  * (or a decorator that implements the {@link net.sf.ehcache.Ehcache} interface),
42  * representing a cache region within an EHCache {@link net.sf.ehcache.CacheManager}.
43  *
44  * <p>If the specified named cache is not configured in the cache configuration descriptor,
45  * this FactoryBean will construct an instance of a Cache with the provided name and the
46  * specified cache properties and add it to the CacheManager for later retrieval. If some
47  * or all properties are not set at configuration time, this FactoryBean will use defaults.
48  *
49  * <p>Note: If the named Cache instance is found, the properties will be ignored and the
50  * Cache instance will be retrieved from the CacheManager.
51  *
52  * <p>Note: As of Spring 2.0, this FactoryBean is based on EHCache 1.2's API (in particular
53  * the Ehcache interface and the extended Cache constructor). It is not compatible with
54  * EHCache 1.1 anymore; please upgrade to EHCache 1.2.3 or higher.
55  *
56  * @author Dmitriy Kopylenko
57  * @author Juergen Hoeller
58  * @since 1.1.1
59  * @see #setCacheManager
60  * @see EhCacheManagerFactoryBean
61  * @see net.sf.ehcache.Cache
62  */

63 public class EhCacheFactoryBean implements FactoryBean, BeanNameAware, InitializingBean {
64
65     protected final Log logger = LogFactory.getLog(getClass());
66
67     private CacheManager cacheManager;
68
69     private String JavaDoc cacheName;
70
71     private int maxElementsInMemory = 10000;
72
73     private MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = MemoryStoreEvictionPolicy.LRU;
74
75     private boolean overflowToDisk = true;
76
77     private String JavaDoc diskStorePath;
78
79     private boolean eternal = false;
80
81     private int timeToLive = 120;
82
83     private int timeToIdle = 120;
84
85     private boolean diskPersistent = false;
86
87     private int diskExpiryThreadIntervalSeconds = 120;
88
89     private boolean blocking = false;
90
91     private CacheEntryFactory cacheEntryFactory;
92
93     private String JavaDoc beanName;
94
95     private Ehcache cache;
96
97
98     /**
99      * Set a CacheManager from which to retrieve a named Cache instance.
100      * By default, <code>CacheManager.getInstance()</code> will be called.
101      * <p>Note that in particular for persistent caches, it is advisable to
102      * properly handle the shutdown of the CacheManager: Set up a separate
103      * EhCacheManagerFactoryBean and pass a reference to this bean property.
104      * <p>A separate EhCacheManagerFactoryBean is also necessary for loading
105      * EHCache configuration from a non-default config location.
106      * @see EhCacheManagerFactoryBean
107      * @see net.sf.ehcache.CacheManager#getInstance
108      */

109     public void setCacheManager(CacheManager cacheManager) {
110         this.cacheManager = cacheManager;
111     }
112
113     /**
114      * Set a name for which to retrieve or create a cache instance.
115      * Default is the bean name of this EhCacheFactoryBean.
116      */

117     public void setCacheName(String JavaDoc cacheName) {
118         this.cacheName = cacheName;
119     }
120
121     /**
122      * Specify the maximum number of cached objects in memory.
123      * Default is 10000 elements.
124      */

125     public void setMaxElementsInMemory(int maxElementsInMemory) {
126         this.maxElementsInMemory = maxElementsInMemory;
127     }
128
129     /**
130      * Set the memory style eviction policy for this cache.
131      * Supported values are "LRU", "LFU" and "FIFO", according to the
132      * constants defined in EHCache's MemoryStoreEvictionPolicy class.
133      * Default is "LRU".
134      */

135     public void setMemoryStoreEvictionPolicy(MemoryStoreEvictionPolicy memoryStoreEvictionPolicy) {
136         Assert.notNull(memoryStoreEvictionPolicy, "memoryStoreEvictionPolicy must not be null");
137         this.memoryStoreEvictionPolicy = memoryStoreEvictionPolicy;
138     }
139
140     /**
141      * Set whether elements can overflow to disk when the in-memory cache
142      * has reached the maximum size limit. Default is "true".
143      */

144     public void setOverflowToDisk(boolean overflowToDisk) {
145         this.overflowToDisk = overflowToDisk;
146     }
147
148     /**
149      * Set the location of temporary files for the disk store of this cache.
150      * Default is the CacheManager's disk store path.
151      */

152     public void setDiskStorePath(String JavaDoc diskStorePath) {
153         this.diskStorePath = diskStorePath;
154     }
155
156     /**
157      * Set whether elements are considered as eternal. If "true", timeouts
158      * are ignored and the element is never expired. Default is "false".
159      */

160     public void setEternal(boolean eternal) {
161         this.eternal = eternal;
162     }
163
164     /**
165      * Set t he time in seconds to live for an element before it expires,
166      * i.e. the maximum time between creation time and when an element expires.
167      * It is only used if the element is not eternal. Default is 120 seconds.
168      */

169     public void setTimeToLive(int timeToLive) {
170         this.timeToLive = timeToLive;
171     }
172
173     /**
174      * Set the time in seconds to idle for an element before it expires, that is,
175      * the maximum amount of time between accesses before an element expires.
176      * This is only used if the element is not eternal. Default is 120 seconds.
177      */

178     public void setTimeToIdle(int timeToIdle) {
179         this.timeToIdle = timeToIdle;
180     }
181
182     /**
183      * Set whether the disk store persists between restarts of the Virtual Machine.
184      * The default is "false".
185      */

186     public void setDiskPersistent(boolean diskPersistent) {
187         this.diskPersistent = diskPersistent;
188     }
189
190     /**
191      * Set the number of seconds between runs of the disk expiry thread.
192      * The default is 120 seconds.
193      */

194     public void setDiskExpiryThreadIntervalSeconds(int diskExpiryThreadIntervalSeconds) {
195         this.diskExpiryThreadIntervalSeconds = diskExpiryThreadIntervalSeconds;
196     }
197
198     /**
199      * Set whether to use a blocking cache that lets read attempts block
200      * until the requested element is created.
201      * <p>If you intend to build a self-populating blocking cache,
202      * consider specifying a {@link #setCacheEntryFactory CacheEntryFactory}.
203      * @see net.sf.ehcache.constructs.blocking.BlockingCache
204      * @see #setCacheEntryFactory
205      */

206     public void setBlocking(boolean blocking) {
207         this.blocking = blocking;
208     }
209
210     /**
211      * Set an EHCache {@link net.sf.ehcache.constructs.blocking.CacheEntryFactory}
212      * to use for a self-populating cache. If such a factory is specified,
213      * the cache will be decorated with EHCache's
214      * {@link net.sf.ehcache.constructs.blocking.SelfPopulatingCache}.
215      * <p>The specified factory can be of type
216      * {@link net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory},
217      * which will lead to the use of an
218      * {@link net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache}.
219      * <p>Note: Any such self-populating cache is automatically a blocking cache.
220      * @see net.sf.ehcache.constructs.blocking.SelfPopulatingCache
221      * @see net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache
222      * @see net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory
223      */

224     public void setCacheEntryFactory(CacheEntryFactory cacheEntryFactory) {
225         this.cacheEntryFactory = cacheEntryFactory;
226     }
227
228     public void setBeanName(String JavaDoc name) {
229         this.beanName = name;
230     }
231
232
233     public void afterPropertiesSet() throws CacheException, IOException JavaDoc {
234         // If no CacheManager given, fetch the default.
235
if (this.cacheManager == null) {
236             if (logger.isDebugEnabled()) {
237                 logger.debug("Using default EHCache CacheManager for cache region '" + this.cacheName + "'");
238             }
239             this.cacheManager = CacheManager.getInstance();
240         }
241
242         // If no cache name given, use bean name as cache name.
243
if (this.cacheName == null) {
244             this.cacheName = this.beanName;
245         }
246
247         // Fetch cache region: If none with the given name exists,
248
// create one on the fly.
249
if (this.cacheManager.cacheExists(this.cacheName)) {
250             if (logger.isDebugEnabled()) {
251                 logger.debug("Using existing EHCache cache region '" + this.cacheName + "'");
252             }
253             this.cache = this.cacheManager.getEhcache(this.cacheName);
254         }
255         else {
256             if (logger.isDebugEnabled()) {
257                 logger.debug("Creating new EHCache cache region '" + this.cacheName + "'");
258             }
259             Cache rawCache = createCache();
260             this.cacheManager.addCache(rawCache);
261             Ehcache decoratedCache = decorateCache(rawCache);
262             this.cacheManager.replaceCacheWithDecoratedCache(rawCache, decoratedCache);
263             this.cache = decoratedCache;
264         }
265     }
266
267     /**
268      * Create a raw Cache object based on the configuration of this FactoryBean.
269      */

270     private Cache createCache() {
271         return new Cache(
272                 this.cacheName, this.maxElementsInMemory, this.memoryStoreEvictionPolicy,
273                 this.overflowToDisk, this.diskStorePath, this.eternal, this.timeToLive, this.timeToIdle,
274                 this.diskPersistent, this.diskExpiryThreadIntervalSeconds, null);
275     }
276
277     /**
278      * Decorate the given Cache, if necessary.
279      * <p>The default implementation simply returns the given cache object as-is.
280      * @param cache the raw Cache object, based on the configuration of this FactoryBean
281      * @return the (potentially decorated) cache object to be registered with the CacheManager
282      */

283     protected Ehcache decorateCache(Cache cache) {
284         if (this.cacheEntryFactory != null) {
285             if (this.cacheEntryFactory instanceof UpdatingCacheEntryFactory) {
286                 return new UpdatingSelfPopulatingCache(cache, (UpdatingCacheEntryFactory) this.cacheEntryFactory);
287             }
288             else {
289                 return new SelfPopulatingCache(cache, this.cacheEntryFactory);
290             }
291         }
292         if (this.blocking) {
293             return new BlockingCache(cache);
294         }
295         return cache;
296     }
297
298
299     public Object JavaDoc getObject() {
300         return this.cache;
301     }
302
303     public Class JavaDoc getObjectType() {
304         return (this.cache != null ? this.cache.getClass() : Ehcache.class);
305     }
306
307     public boolean isSingleton() {
308         return true;
309     }
310
311 }
312
Popular Tags