上一篇文章说了默认的缓存实际上是:ConcurrentMap,有很多功能都没有,比如:定期删除、容量上线、容量不够的策略(LRU、LFU)等等。
自定义缓存步骤
1. 定义一个属于自己的Cache,需要实现org.springframework.cache.Cache
public class MyCache implements Cache {
private MyLinkedHashMap<String> myMap = new MyLinkedHashMap<>(2, 1, true);
private String name;
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Object getNativeCache() {
return myMap;
}
@Override
public ValueWrapper get(Object key) {
String value = myMap.get(key);
return value == null ? null : () -> value;
}
@Override
public <T> T get(Object key, Class<T> type) {
Object value = myMap.get(key);
if (value != null && type != null && !type.isInstance(value)) {
throw new IllegalStateException(
"Cached value is not of required type [" + type.getName() + "]: " + value);
}
return (T) value;
}
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
return Optional.ofNullable((T) myMap.get(key)).orElseGet(() -> {
try {
return valueLoader.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
@Override
public void put(Object key, Object value) {
myMap.put((String) key, (String) value);
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
return () -> Optional.ofNullable((Object) myMap.get(key)).orElse(value);
}
@Override
public void evict(Object key) {
}
@Override
public boolean evictIfPresent(Object key) {
return false;
}
@Override
public void clear() {
myMap.clear();
}
@Override
public boolean invalidate() {
return false;
}
}
2. 重写缓存底层数据结构(当然也可以用Java自带的数据结构,比如:HashMap、LinkedHashMap、ConcurrentMap等)
public class MyLinkedHashMap<T> extends LinkedHashMap<String, T> {
private int capacity;
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > capacity;
}
public MyLinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
//可选参数accessOrder 设置为true 即可实现LRU逻辑
super(initialCapacity, loadFactor, accessOrder);
this.capacity = initialCapacity;
}
}
3. 注入到SimpleCacheManager
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 自定义cache -->
<bean class="com.dong.springuseehcacheredis.cache.MyCache">
<property name="name" value="帅东自定义cache"/>
</bean>
</set>
</property>
</bean>
</beans>
GitHub代码
https://github.com/shuaidongshuai/spring-use-ehcache-redis