Commit ab4a3aa5a16a124cf6f96ce237256958345d36de

Authored by ci-aliyun
1 parent 31c81ff7

#feat:增加CacheKeyGenerator

README.md
... ... @@ -24,3 +24,6 @@ spring:
24 24 pool:
25 25 max-wait: 1
26 26 ```
  27 +
  28 +### v1.2.1
  29 +- 增加了KeyGenerator实现类,实现类中使用className.methodName:params拼接成key
... ...
... ... @@ -6,7 +6,7 @@
6 6  
7 7 <groupId>com.irrigation</groupId>
8 8 <artifactId>common-lib</artifactId>
9   - <version>1.2.0</version>
  9 + <version>1.2.1</version>
10 10  
11 11 <properties>
12 12 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
... ...
src/main/java/com/irrigation/icl/cache/core/CustomCacheKeyGenerator.java 0 → 100644
  1 +package com.irrigation.icl.cache.core;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.springframework.cache.interceptor.KeyGenerator;
  5 +import org.springframework.util.StringUtils;
  6 +
  7 +import java.lang.reflect.Method;
  8 +
  9 +/**
  10 + * @Author: boni
  11 + * @Date: 2018/9/4-下午3:20
  12 + */
  13 +@Slf4j
  14 +public class CustomCacheKeyGenerator implements KeyGenerator {
  15 + public static final int NO_PARAM_KEY = 0;
  16 +
  17 + @Override
  18 + public Object generate(Object target, Method method, Object... params) {
  19 + StringBuilder key = new StringBuilder();
  20 + key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":");
  21 + if (params.length == 0) {
  22 + return key.append(NO_PARAM_KEY).toString();
  23 + }
  24 + key.append(StringUtils.arrayToCommaDelimitedString(params));
  25 + //String finalKey = key.toString();
  26 + //log.debug("using cache key={}", finalKey);
  27 + return key.toString();
  28 + }
  29 +}
... ...
src/main/java/com/irrigation/icl/cache/core/LayeringCache.java
... ... @@ -6,17 +6,18 @@ import net.sf.ehcache.CacheException;
6 6 import net.sf.ehcache.CacheManager;
7 7 import net.sf.ehcache.Ehcache;
8 8 import net.sf.ehcache.Element;
9   -import net.sf.ehcache.config.CacheConfiguration;
10   -import net.sf.ehcache.config.Configuration;
11   -import net.sf.ehcache.config.DiskStoreConfiguration;
12   -import net.sf.ehcache.config.PersistenceConfiguration;
  9 +import net.sf.ehcache.config.*;
13 10 import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
  11 +import net.sf.ehcache.store.compound.ReadWriteCopyStrategy;
14 12 import org.springframework.cache.Cache;
  13 +import org.springframework.cache.ehcache.EhCacheCacheManager;
  14 +import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
15 15 import org.springframework.cache.support.SimpleValueWrapper;
16 16 import org.springframework.data.redis.cache.RedisCache;
17 17 import org.springframework.data.redis.core.RedisOperations;
18 18 import org.springframework.util.StopWatch;
19 19  
  20 +import java.io.Serializable;
20 21 import java.sql.Time;
21 22 import java.text.SimpleDateFormat;
22 23 import java.time.LocalDateTime;
... ... @@ -83,7 +84,8 @@ public class LayeringCache extends RedisCache {
83 84 // 先更新1级然后再更新2级;允许短时间内的数据不一致
84 85 if (layerL1Enable) {
85 86 Ehcache ehCache = getL1Cache(super.getName());
86   - ehCache.put(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
  87 + ehCache.put(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1()
  88 + .getLocalTimeToLiveSeconds()));
87 89 layeringCacheManager.publishMessage(Command.set(this.ID, super.getName(), String.valueOf(key)));
88 90 }
89 91 super.put(key, value);
... ... @@ -106,7 +108,8 @@ public class LayeringCache extends RedisCache {
106 108 public Cache.ValueWrapper putIfAbsent(Object key, final Object value) {
107 109 if (layerL1Enable) {
108 110 Ehcache ehCache = getL1Cache(super.getName());
109   - ehCache.putIfAbsent(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
  111 + ehCache.putIfAbsent(new Element(key, value, false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties
  112 + .getCacheL1().getLocalTimeToLiveSeconds()));
110 113 layeringCacheManager.publishMessage(Command.set(this.ID, super.getName(), String.valueOf(key)));
111 114 }
112 115 Cache.ValueWrapper wrapper = super.putIfAbsent(key, value);
... ... @@ -125,7 +128,8 @@ public class LayeringCache extends RedisCache {
125 128 Cache.ValueWrapper wrapper = super.get(command.getKey());
126 129 if (wrapper != null) {
127 130 Ehcache ehCache = getL1Cache(super.getName());
128   - ehCache.put(new Element(command.getKey(), wrapper.get(), false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(), layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
  131 + ehCache.put(new Element(command.getKey(), wrapper.get(), false, layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds(),
  132 + layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds()));
129 133 log.info("Update Cache L1 {} - {}", command.getKey(), wrapper.get());
130 134 }
131 135 break;
... ... @@ -142,9 +146,12 @@ public class LayeringCache extends RedisCache {
142 146 Future<Ehcache> future = this.layeringL1CacheContainer.get(name);
143 147 if (future == null) {
144 148 Callable<Ehcache> callable = () -> {
145   - Ehcache cache = layeringL1CacheManager.getEhcache(name);
  149 + Ehcache cache = layeringL1CacheManager.getCache(name);
146 150 if (cache == null) {
147   - layeringL1CacheManager.addCache(name);
  151 + CacheConfiguration cacheConfiguration = getCacheConfiguration();
  152 + cacheConfiguration.setName(name);
  153 + Ehcache ehcache = new net.sf.ehcache.Cache(cacheConfiguration);
  154 + layeringL1CacheManager.addCache(ehcache);
148 155 cache = layeringL1CacheManager.getEhcache(name);
149 156 }
150 157 return cache;
... ... @@ -165,12 +172,42 @@ public class LayeringCache extends RedisCache {
165 172  
166 173 }
167 174  
  175 +
168 176 private String getDate() {
169 177 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
170 178  
171 179 return simpleDateFormat.format(new Date());
172 180 }
173 181  
  182 + private CacheConfiguration getCacheConfiguration() {
  183 + // Cache
  184 + CacheConfiguration cacheConfiguration = new CacheConfiguration();
  185 + cacheConfiguration.setEternal(false);
  186 +
  187 + PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration();
  188 + persistenceConfiguration.setStrategy(PersistenceConfiguration.Strategy.NONE.name());
  189 +
  190 + cacheConfiguration.persistence(persistenceConfiguration);
  191 + cacheConfiguration.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);
  192 + cacheConfiguration.setDiskExpiryThreadIntervalSeconds(layeringCacheProperties.getCacheL1().getLocalDiskExpiryThreadIntervalSeconds());
  193 + // 默认false,使用引用.设置为true,避免外部代码修改了缓存对象.造成EhCache的缓存对象也随之改变
  194 + // 但是设置为true后,将引起element的tti不自动刷新.如果直接新建element去覆盖原值.则本地ttl和远程ttl会产生一定的误差.
  195 + // 因此,使用时放弃手动覆盖方式刷新本地tti,当本地tti过期后,自动从Redis中再获取即可.
  196 + cacheConfiguration.copyOnRead(true);
  197 + cacheConfiguration.copyOnWrite(true);
  198 +
  199 +// CopyStrategyConfiguration copyStrategyConfiguration = new CopyStrategyConfiguration();
  200 +// copyStrategyConfiguration.setClass(MyCopyStrategy.class.getName());
  201 +// copyStrategyConfiguration.setCopyStrategyInstance(new MyCopyStrategy());
  202 +
  203 +// cacheConfiguration.addCopyStrategy(copyStrategyConfiguration);
  204 +
  205 + cacheConfiguration.setTimeToIdleSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds());
  206 + cacheConfiguration.setTimeToLiveSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds());
  207 +
  208 + return cacheConfiguration;
  209 + }
  210 +
174 211 private void initEhcache() {
175 212 if (layerL1Enable) {
176 213 this.ID = layeringCacheProperties.getCacheL1().getKey() + "." + getDate();
... ... @@ -192,30 +229,35 @@ public class LayeringCache extends RedisCache {
192 229 dsc.setPath(layeringCacheProperties.getCacheL1().getLocalStoreLocation() + this.ID);
193 230 configuration.diskStore(dsc);
194 231  
195   - PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration();
196   - persistenceConfiguration.setStrategy(PersistenceConfiguration.Strategy.NONE.name());
197   -
198   - // Cache
199   - CacheConfiguration cacheConfiguration = new CacheConfiguration();
200   - cacheConfiguration.setEternal(false);
201   -
202   - cacheConfiguration.persistence(persistenceConfiguration);
203   - cacheConfiguration.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);
204   - cacheConfiguration.setDiskExpiryThreadIntervalSeconds(layeringCacheProperties.getCacheL1().getLocalDiskExpiryThreadIntervalSeconds());
205   - // 默认false,使用引用.设置为true,避免外部代码修改了缓存对象.造成EhCache的缓存对象也随之改变
206   - // 但是设置为true后,将引起element的tti不自动刷新.如果直接新建element去覆盖原值.则本地ttl和远程ttl会产生一定的误差.
207   - // 因此,使用时放弃手动覆盖方式刷新本地tti,当本地tti过期后,自动从Redis中再获取即可.
208   - cacheConfiguration.copyOnRead(true);
209   - cacheConfiguration.copyOnWrite(true);
210   -
211   - cacheConfiguration.setTimeToIdleSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToIdleSeconds());
212   - cacheConfiguration.setTimeToLiveSeconds(layeringCacheProperties.getCacheL1().getLocalTimeToLiveSeconds());
  232 + CacheConfiguration cacheConfiguration = getCacheConfiguration();
213 233  
214 234 configuration.setDefaultCacheConfiguration(cacheConfiguration);
215 235 configuration.setDynamicConfig(false);
216 236 configuration.setUpdateCheck(false);
217 237  
  238 +
218 239 layeringL1CacheManager = new CacheManager(configuration);
219 240 }
220 241 }
  242 +
  243 + class MyCopyStrategy implements ReadWriteCopyStrategy<Element> {
  244 + @Override
  245 + public Element copyForWrite(Element value) {
  246 + if (value != null) {
  247 + Object temp = (Serializable) value.getObjectValue();
  248 + return new Element(value.getObjectKey(), temp);
  249 + }
  250 + return value;
  251 + }
  252 +
  253 + @Override
  254 + public Element copyForRead(Element storedValue) {
  255 + if (storedValue != null) {
  256 + Object temp = (Serializable) storedValue.getObjectValue();
  257 + return new Element(storedValue.getObjectKey(), temp);
  258 + }
  259 + return storedValue;
  260 +
  261 + }
  262 + }
221 263 }
... ...