diff --git a/README.md b/README.md
index 0634140..55fed43 100644
--- a/README.md
+++ b/README.md
@@ -24,3 +24,6 @@ spring:
pool:
max-wait: 1
```
+
+### v1.2.1
+- 增加了KeyGenerator实现类,实现类中使用className.methodName:params拼接成key
diff --git a/pom.xml b/pom.xml
index b942a7d..1008cb4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.irrigation
common-lib
- 1.2.0
+ 1.2.1
UTF-8
diff --git a/src/main/java/com/irrigation/icl/cache/core/CustomCacheKeyGenerator.java b/src/main/java/com/irrigation/icl/cache/core/CustomCacheKeyGenerator.java
new file mode 100644
index 0000000..55120ad
--- /dev/null
+++ b/src/main/java/com/irrigation/icl/cache/core/CustomCacheKeyGenerator.java
@@ -0,0 +1,29 @@
+package com.irrigation.icl.cache.core;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.util.StringUtils;
+
+import java.lang.reflect.Method;
+
+/**
+ * @Author: boni
+ * @Date: 2018/9/4-下午3:20
+ */
+@Slf4j
+public class CustomCacheKeyGenerator implements KeyGenerator {
+ public static final int NO_PARAM_KEY = 0;
+
+ @Override
+ public Object generate(Object target, Method method, Object... params) {
+ StringBuilder key = new StringBuilder();
+ key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
+ if (params.length == 0) {
+ return key.append(NO_PARAM_KEY).toString();
+ }
+ key.append(StringUtils.arrayToCommaDelimitedString(params));
+ //String finalKey = key.toString();
+ //log.debug("using cache key={}", finalKey);
+ return key.toString();
+ }
+}
diff --git a/src/main/java/com/irrigation/icl/cache/core/LayeringCache.java b/src/main/java/com/irrigation/icl/cache/core/LayeringCache.java
index f9886b6..4d0d580 100644
--- a/src/main/java/com/irrigation/icl/cache/core/LayeringCache.java
+++ b/src/main/java/com/irrigation/icl/cache/core/LayeringCache.java
@@ -6,17 +6,18 @@ import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
-import net.sf.ehcache.config.CacheConfiguration;
-import net.sf.ehcache.config.Configuration;
-import net.sf.ehcache.config.DiskStoreConfiguration;
-import net.sf.ehcache.config.PersistenceConfiguration;
+import net.sf.ehcache.config.*;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+import net.sf.ehcache.store.compound.ReadWriteCopyStrategy;
import org.springframework.cache.Cache;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.StopWatch;
+import java.io.Serializable;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
@@ -83,7 +84,8 @@ public class LayeringCache extends RedisCache {
// 先更新1级然后再更新2级;允许短时间内的数据不一致
if (layerL1Enable) {
Ehcache ehCache = getL1Cache(super.getName());
- ehCache.put(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
+ ehCache.put(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1()
+ .getLocalTimeToLiveSeconds()));
layeringCacheManager.publishMessage(Command.set(this.ID, super.getName(), String.valueOf(key)));
}
super.put(key, value);
@@ -106,7 +108,8 @@ public class LayeringCache extends RedisCache {
public Cache.ValueWrapper putIfAbsent(Object key, final Object value) {
if (layerL1Enable) {
Ehcache ehCache = getL1Cache(super.getName());
- ehCache.putIfAbsent(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
+ ehCache.putIfAbsent(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties
+ .getCacheL1().getLocalTimeToLiveSeconds()));
layeringCacheManager.publishMessage(Command.set(this.ID, super.getName(), String.valueOf(key)));
}
Cache.ValueWrapper wrapper = super.putIfAbsent(key, value);
@@ -125,7 +128,8 @@ public class LayeringCache extends RedisCache {
Cache.ValueWrapper wrapper = super.get(command.getKey());
if (wrapper != null) {
Ehcache ehCache = getL1Cache(super.getName());
- ehCache.put(new Element(command.getKey(), wrapper.get(), false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
+ ehCache.put(new Element(command.getKey(), wrapper.get(), false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(),
+ layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
log.info("Update Cache L1 {} - {}", command.getKey(), wrapper.get());
}
break;
@@ -142,9 +146,12 @@ public class LayeringCache extends RedisCache {
Future future = this.layeringL1CacheContainer.get(name);
if (future == null) {
Callable callable = () -> {
- Ehcache cache = layeringL1CacheManager.getEhcache(name);
+ Ehcache cache = layeringL1CacheManager.getCache(name);
if (cache == null) {
- layeringL1CacheManager.addCache(name);
+ CacheConfiguration cacheConfiguration = getCacheConfiguration();
+ cacheConfiguration.setName(name);
+ Ehcache ehcache = new net.sf.ehcache.Cache(cacheConfiguration);
+ layeringL1CacheManager.addCache(ehcache);
cache = layeringL1CacheManager.getEhcache(name);
}
return cache;
@@ -165,12 +172,42 @@ public class LayeringCache extends RedisCache {
}
+
private String getDate() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return simpleDateFormat.format(new Date());
}
+ private CacheConfiguration getCacheConfiguration() {
+ // Cache
+ CacheConfiguration cacheConfiguration = new CacheConfiguration();
+ cacheConfiguration.setEternal(false);
+
+ PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration();
+ persistenceConfiguration.setStrategy(PersistenceConfiguration.Strategy.NONE.name());
+
+ cacheConfiguration.persistence(persistenceConfiguration);
+ cacheConfiguration.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);
+ cacheConfiguration.setDiskExpiryThreadIntervalSeconds(layeringCacheProperties.getCacheL1().getLocalDiskExpiryThreadIntervalSeconds());
+ // 默认false,使用引用.设置为true,避免外部代码修改了缓存对象.造成EhCache的缓存对象也随之改变
+ // 但是设置为true后,将引起element的tti不自动刷新.如果直接新建element去覆盖原值.则本地ttl和远程ttl会产生一定的误差.
+ // 因此,使用时放弃手动覆盖方式刷新本地tti,当本地tti过期后,自动从Redis中再获取即可.
+ cacheConfiguration.copyOnRead(true);
+ cacheConfiguration.copyOnWrite(true);
+
+// CopyStrategyConfiguration copyStrategyConfiguration = new CopyStrategyConfiguration();
+// copyStrategyConfiguration.setClass(MyCopyStrategy.class.getName());
+// copyStrategyConfiguration.setCopyStrategyInstance(new MyCopyStrategy());
+
+// cacheConfiguration.addCopyStrategy(copyStrategyConfiguration);
+
+ cacheConfiguration.setTimeToIdleSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds());
+ cacheConfiguration.setTimeToLiveSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds());
+
+ return cacheConfiguration;
+ }
+
private void initEhcache() {
if (layerL1Enable) {
this.ID = layeringCacheProperties.getCacheL1().getKey() + "." + getDate();
@@ -192,30 +229,35 @@ public class LayeringCache extends RedisCache {
dsc.setPath(layeringCacheProperties.getCacheL1().getLocalStoreLocation() + this.ID);
configuration.diskStore(dsc);
- PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration();
- persistenceConfiguration.setStrategy(PersistenceConfiguration.Strategy.NONE.name());
-
- // Cache
- CacheConfiguration cacheConfiguration = new CacheConfiguration();
- cacheConfiguration.setEternal(false);
-
- cacheConfiguration.persistence(persistenceConfiguration);
- cacheConfiguration.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);
- cacheConfiguration.setDiskExpiryThreadIntervalSeconds(layeringCacheProperties.getCacheL1().getLocalDiskExpiryThreadIntervalSeconds());
- // 默认false,使用引用.设置为true,避免外部代码修改了缓存对象.造成EhCache的缓存对象也随之改变
- // 但是设置为true后,将引起element的tti不自动刷新.如果直接新建element去覆盖原值.则本地ttl和远程ttl会产生一定的误差.
- // 因此,使用时放弃手动覆盖方式刷新本地tti,当本地tti过期后,自动从Redis中再获取即可.
- cacheConfiguration.copyOnRead(true);
- cacheConfiguration.copyOnWrite(true);
-
- cacheConfiguration.setTimeToIdleSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds());
- cacheConfiguration.setTimeToLiveSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds());
+ CacheConfiguration cacheConfiguration = getCacheConfiguration();
configuration.setDefaultCacheConfiguration(cacheConfiguration);
configuration.setDynamicConfig(false);
configuration.setUpdateCheck(false);
+
layeringL1CacheManager = new CacheManager(configuration);
}
}
+
+ class MyCopyStrategy implements ReadWriteCopyStrategy {
+ @Override
+ public Element copyForWrite(Element value) {
+ if (value != null) {
+ Object temp = (Serializable) value.getObjectValue();
+ return new Element(value.getObjectKey(), temp);
+ }
+ return value;
+ }
+
+ @Override
+ public Element copyForRead(Element storedValue) {
+ if (storedValue != null) {
+ Object temp = (Serializable) storedValue.getObjectValue();
+ return new Element(storedValue.getObjectKey(), temp);
+ }
+ return storedValue;
+
+ }
+ }
}