我想在grails服务中使用ehcache会话范围。
我设法在config / resources.groovy
中有一个来自此定义的缓存beanmyCache(org.springframework.cache.ehcache.EhCacheFactoryBean) {
timeToIdle = 5000 // life span in seconds
timeToLive = 5000 // life span in seconds
}
但是从工厂获得的对象是单例范围的。
在会话范围服务中使用会话作用域ehcache的最佳方法是什么?
谢谢
答案 0 :(得分:2)
您不能使用Ehcache,因为缓存管理器按名称维护缓存,每个名称只能有一个缓存。您需要使用另一个缓存实现,该实现要么不强制使用唯一名称,要么不将该名称用作缓存管理器中的“密钥”。
编辑:这种方法有效,但不使用工厂bean:
import java.util.concurrent.atomic.AtomicInteger
import net.sf.ehcache.Cache
import net.sf.ehcache.CacheManager
import net.sf.ehcache.store.MemoryStoreEvictionPolicy
import org.springframework.beans.factory.DisposableBean
import org.springframework.beans.factory.InitializingBean
class MyService implements InitializingBean, DisposableBean {
private static AtomicInteger counter = new AtomicInteger()
private Cache cache
private String cacheName
static scope = 'session'
void afterPropertiesSet() {
int maxElementsInMemory = 10000
int maxElementsOnDisk = 10000000
MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = MemoryStoreEvictionPolicy.LRU
boolean overflowToDisk = true
boolean eternal = false
int timeToLive = 5000 // 120
int timeToIdle = 5000 // 120
boolean diskPersistent = false
int diskExpiryThreadIntervalSeconds = 120
int diskSpoolBufferSize = 0
cacheName = 'myservice-cache-' + counter.incrementAndGet()
cache = new Cache(cacheName, maxElementsInMemory, memoryStoreEvictionPolicy,
overflowToDisk, null, eternal, timeToLive, timeToIdle,
diskPersistent, diskExpiryThreadIntervalSeconds, null,
null, maxElementsOnDisk, diskSpoolBufferSize)
CacheManager.getInstance().addCache cache
}
void destroy() {
cache.removeAll()
CacheManager.getInstance().removeCache(cacheName)
}
}
由于服务是会话范围的,因此缓存不一定是因为它完全由服务控制。通过实现InitializingBean
,您可以在会话启动时创建缓存,并在会话结束时通过实施DisposableBean
将其删除。随意使用不同的缓存名称方法;这个只是保证它们是独一无二的。此外,我根据EhCacheFactoryBean
中的默认值枚举了缓存构造函数值,但这些值可以内联。