目录
- 一、前言
 - 二、缓存注解
 - 三、实战操作
 - 1、依赖引入
 - 2、yaml配置
 - 3、开启缓存
 - 4、模拟方法
 - 5、测试
 - 6、改造
 
一、前言
Spring Cache本身是Spring框架中一个缓存体系的抽象实现,本身不具备缓存能力,需要配合具体的缓存实现来完成,如Ehcache、Caffeine、Guava、Redis等。
二、缓存注解
- @EnableCaching:开启缓存功能
 - @Cacheable:定义缓存,用于触发缓存
 - @CachePut:定义更新缓存,触发缓存更新
 - @CacheEvict:定义清楚缓存,触发缓存清除
 - @Caching:组合定义多种缓存功能
 - @CacheConfig:定义公共设置,位于class之上
 
三、实战操作
我选择使用目前最受欢迎的Caffeine来作为具体的缓存实现方式,下面是一个demo:
1、依赖引入
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.6</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2、yaml配置
spring:
  cache:
    cache-names: USER
    caffeine:
      spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s
    type: caffeine
Caffeine配置说明
- initialCapacity=[integer]: 初始的缓存空间大小
 - maximumSize=[long]: 缓存的最大条数
 - maximumWeight=[long]: 缓存的最大权重
 - expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期
 - expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期
 - refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
 - weakKeys: 打开key的弱引用
 - weakValues:打开value的弱引用
 - softValues:打开value的软引用
 - recordStats:开发统计功能
 
注意
- expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。
 - maximumSize和maximumWeight不可以同时使用
 - weakValues和softValues不可以同时使用
 
3、开启缓存

4、模拟方法
service层
@Service
@Slf4j
public class CaffeineService {
    public static Map<String, String> map = new HashMap<>();
    static {
        map.put("1", "zhangsan");
        map.put("2", "lisi");
        map.put("3", "wangwu");
    }
    @Cacheable(value = "USER", key = "#id")
    public String getUser(String id) {
        log.info("getUser() run......");
        return map.get(id);
    }
    @CachePut(value = "USER", key = "#id")
    public String updateUser(String id, String name) {
        log.info("updateUser() run......");
        map.put(id, name);
        return map.toString();
    }
    @CacheEvict(value = "USER", key = "#id")
    public String delUser(String id) {
        log.info("delUser() run......");
        map.remove(id);
        return map.toString();
    }
}
controller层
@RestController
@RequestMapping("/cache")
@Slf4j
public class CaffeineController {
    @Autowired
    private CaffeineService caffeineService;
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable String id) {
        long start = System.currentTimeMillis();
        String res = caffeineService.getUser(id);
        long end = System.currentTimeMillis();
        log.info("查询耗时:" + (end - start));
        return res;
    }
    @GetMapping("/user/{id}/{name}")
    public String updateUser(@PathVariable String id, @PathVariable String name) {
        return caffeineService.updateUser(id, name);
    }
    @DeleteMapping("/user/{id}")
    public String delUser(@PathVariable String id) {
        return caffeineService.delUser(id);
    }
}
5、测试
第一次查询:
第二次查询:
查询耗时明显小于第一次查询,因为第二次直接返回缓存,速度提升。
执行更新后再查询:
会使缓存失效。会重新执行查询方法查询
执行删除后再查询:
会使缓存失效。会重新执行查询方法查询

6、改造
上述通过yaml文件配置的方式不够灵活,无法实现多种缓存策略,所以现在一般使用javaconfig的形式进行配置。
下面是示例代码:
@Configuration
public class CaffeineConfig {
    @Bean
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
        List<CaffeineCache> caffeineCaches = new ArrayList<>();
        for (CacheType cacheType : CacheType.values()) {
            caffeineCaches.add(new CaffeineCache(cacheType.name(),
                    Caffeine.newBuilder()
                            .expireAfterWrite(cacheType.getExpires(), TimeUnit.SECONDS)
                            .build()));
        }
        simpleCacheManager.setCaches(caffeineCaches);
        return simpleCacheManager;
    }
}
public enum CacheType {
    USER(5),
    TENANT(20);
    private int expires;
    CacheType(int expires) {
        this.expires = expires;
    }
    public int getExpires() {
        return expires;
    }
}
这样我们就能对USER设置5秒消防时间,对TENANT设置20秒消亡时间,在实际项目中这种方式更加的灵活。
	声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
		
评论(0)