![JAR search and dependency download from the Maven repository](/logo.png)
com.github.bootfastconfig.cache.l2cache.L2Cache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boot-fast-config-cache Show documentation
Show all versions of boot-fast-config-cache Show documentation
Parent pom providing dependency and plugin management for applications
built with Maven
The newest version!
package com.github.bootfastconfig.cache.l2cache;
import com.github.bootfastconfig.cache.CacheMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
/**
* @author mister
*/
public class L2Cache extends AbstractValueAdaptingCache {
private final static Logger log = LoggerFactory.getLogger(L2Cache.class);
private String name;
private Cache cache1;
private Cache cache2;
private String topic;
private Object lock = new Object();
private Consumer eventPublisher;
protected L2Cache(boolean allowNullValues) {
super(allowNullValues);
}
public L2Cache(String name, String topic, Cache cache1, Cache cache2, Consumer eventPublisher) {
super(true);
this.topic = topic;
this.name = name;
this.cache1 = cache1;
this.cache2 = cache2;
this.eventPublisher = eventPublisher;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return this;
}
@SuppressWarnings("unchecked")
@Override
public T get(Object key, Callable valueLoader) {
Object value = lookup(key);
if (value != null) {
return (T) value;
}
synchronized (lock) {
value = lookup(key);
if (value != null) {
return (T) value;
}
try {
value = valueLoader.call();
} catch (Exception ex) {
throw new ValueRetrievalException(key, valueLoader, ex);
}
Object storeValue = toStoreValue(value);
put(key, storeValue);
return (T) value;
}
}
@Override
public void put(Object key, Object value) {
if (!super.isAllowNullValues() && value == null) {
this.evict(key);
return;
}
cache2.put(key, value);
cache1.put(key, value);
eventPublisher.accept(getCacheMessage(key));
}
private CacheMessage getCacheMessage(Object key) {
return new CacheMessage(this.name, key, this.hashCode(), this.topic);
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
ValueWrapper valueWrapper = null;
Object prevValue = null;
// 考虑使用分布式锁,或者将redis的setIfAbsent改为原子性操作
synchronized (lock) {
valueWrapper = cache2.get(key);
if (valueWrapper != null) prevValue = valueWrapper.get();
if (prevValue == null) {
valueWrapper = cache2.putIfAbsent(key, value);
eventPublisher.accept(getCacheMessage(key));
cache1.put(key, toStoreValue(value));
}
}
return valueWrapper;
}
@Override
public void evict(Object key) {
cache2.evict(key);
cache1.evict(key);
eventPublisher.accept(getCacheMessage(key));
}
@Override
public void clear() {
cache2.clear();
cache1.clear();
eventPublisher.accept(getCacheMessage(null));
}
@Override
protected Object lookup(Object key) {
Object value = null;
ValueWrapper valueWrapper = cache1.get(key);
if (valueWrapper != null) value = valueWrapper.get();
if (value != null) {
log.debug("get cache from ehcache, the key is : {}", key);
return value;
}
valueWrapper = cache2.get(key);
if (valueWrapper != null) value = valueWrapper.get();
if (value != null) {
log.debug("get cache from redis and put in ehcache, the key is : {}", key);
cache1.put(key, value);
}
return value;
}
/**
* @param key
* @description 清理本地缓存
*/
private void clearLocal(Object key) {
log.debug("clear local cache, the key is : {}", key);
if (key == null) {
cache1.clear();
} else {
cache1.evict(key);
}
}
/**
* 根据CacheMessage 进行清除缓存
*
* @param cacheMessage
*/
public void clearCache(CacheMessage cacheMessage) {
if (this.name.equals(cacheMessage.getCacheName()) && this.hashCode() != cacheMessage.getSender()) {
clearLocal(cacheMessage.getKey());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy