SpringBoot自定义缓存

上一篇文章说了默认的缓存实际上是: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


<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>
                
                <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

你可能感兴趣的:(JAVA,缓存,spring,boot,java)