SpringBoot2 缓存的使用(@CacheConfig @Cacheable @CacheEvict)

1: 引入依赖( 以Caffeine为例, 要用Redis的自行替换依赖&配置以及CacheManager的注册)

        <!-- 缓存 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>

2: 配置文件添加配置

spring.cache.type=caffeine

3: 配置类 @EnableCaching 并且注册CacheManager, 配置缓存key生成策略(可选)

配置类

/**
 * @author xudaz
 */
@Configuration
@EnableCaching
public class MybatisPlusConfig {

    /**
     * 定义cache名称、超时时长(秒)、最大容量
     * 每个cache缺省:10秒超时、最多缓存50000条数据,需要修改可以在构造方法的参数中指定。
     */
    @AllArgsConstructor
    public enum Caches {
        /**
         * 有效期600秒
         */
        nulls(600, 100),
        /**
         * 有效期2个小时 , 最大容量1000
         */
        user(7200, 1000),
        /**
         * 有效期2个小时 , 最大容量1000
         */
        order(7200, 1000),
        ;

        /**
         * 最大數量
         */
        private final int maxSize;
        /**
         * //过期时间(秒)
         */
        private final int ttl;

        public int getMaxSize() {
            return maxSize;
        }

        public int getTtl() {
            return ttl;
        }
    }

    /**
     * 创建基于 Caffeine 的Cache Manager
     *
     * @return r
     */
    @Bean
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        ArrayList<CaffeineCache> caches = new ArrayList<>();
        for (Caches c : Caches.values()) {
            caches.add(new CaffeineCache(c.name(),
                    Caffeine.newBuilder().recordStats()
                            .expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
                            .maximumSize(c.getMaxSize())
                            .build())
            );
        }
        cacheManager.setCaches(caches);
        return cacheManager;
    }

}

key生成策略(这是我写的 大家可以自己发挥)


import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;

/**
 *   缓存生成策略
 * @author xudaz
 * @date 2021/6/15
 */
@Component("MyKeyGenerator")
@Slf4j
public class MyKeyGenerator implements KeyGenerator {


    @SuppressWarnings("NullableProblems")
    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder builder = new StringBuilder(target.getClass().getSimpleName()).append(".").append(method.getName());
        for (Object param : params) {
            if ( null == param ) {
                continue;
            }
            // 参数为map自定义key=类名+方法名+map的key-value值
            if (param instanceof Map) {
                // 分隔符
                String sp = ".";
                @SuppressWarnings("unchecked") Map<String, Object> map = (Map<String, Object>) param;
                if (map.isEmpty()) {
                    continue;
                }
                for (String key : map.keySet()) {
                    builder.append(key).append("-").append(map.get(key)).append(sp);
                }
            }
            // 如果是集合
            else if (param instanceof Collection) {
                // 分隔符
                String sp = ",";
                @SuppressWarnings("unchecked") Collection<Object> collection = (Collection<Object>) param;
                if (collection.isEmpty()) {
                    continue;
                }
                for (Object key : collection) {
                    builder.append(key).append(sp);
                }
            }
            // 如果是 Wrapper
             else if (param instanceof AbstractWrapper) {
                AbstractWrapper<?,?,?> wrapper = (AbstractWrapper<?,?,?>) param;
                StringBuilder targetSql = new StringBuilder(wrapper.getTargetSql());
                Map<String, Object> paramNameValuePairs = wrapper.getParamNameValuePairs();
                paramNameValuePairs.forEach((key, value) -> targetSql.append(", ").append(value));

                builder.append(targetSql).append("; ");
            } else {
                builder.append(param);
            }
        }
        log.info("cache key ==> " + builder);
        return new SimpleKey(builder.toString());
    }

}

4: 使用 @Cacheable开启缓存 @CacheEvict清除缓存 @CacheConfig放在类上面配置公共属性

1, @Cacheable

属性
1: cacheNames/value 缓存名字 必须是上面配置枚举类里的
2: key 缓存键 可以理解为缓存Map里的key key一致才能命中缓存
3: keyGenerator 缓存键生成策略 填写自己继承了org.springframework.cache.interceptor.KeyGenerator的类
如我上面的”MyKeyGenerator”

2, @CacheConfig (类公共配置)

属性
1: cacheNames/value 同上
2: keyGenerator 同上

3, @CacheEvict(清除缓存)

属性
1: cacheNames/value 同上
2: keyGenerator 同上
3: allEntries 是否删除缓存中的所有条目
… 其他属性暂时没研究

5: 简单示例

SpringBoot2 缓存的使用(@CacheConfig @Cacheable @CacheEvict)

使用缓存

SpringBoot2 缓存的使用(@CacheConfig @Cacheable @CacheEvict)

清除缓存

SpringBoot2 缓存的使用(@CacheConfig @Cacheable @CacheEvict)

END

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容