Google Guava Cache是一种非常优秀本地缓存解决方案,提供了基于容量,时间和引用的缓存回收方式。基于容量的方式内部实现采用LRU算法,基于引用回收很好的利用了Java虚拟机的垃圾回收机制。其中的缓存构造器CacheBuilder采用构建者模式提供了设置好各种参数的缓存对象,缓存核心类LocalCache里面的内部类Segment与jdk1.7及以前的ConcurrentHashMap非常相似,都继承于ReetrantLock,还有六个队列,以实现丰富的本地缓存方案。 通俗的讲,Guva是google开源的一个公共java库,类似于Apache Commons,它提供了集合,反射,缓存,科学计算,xml,io等一些工具类库。cache只是其中的一个模块。使用Guva cache能够方便快速的构建本地缓存。
Caffeine是使用Java8对Guava缓存的重写版本 ,在Spring Boot 2.0中将取代Guava。如果出现Caffeine,
CaffeineCacheManager将会自动配置。
相对于IO操作 速度快,效率高 相对于Redis Redis是一种优秀的分布式缓存实现,受限于网卡等原因,远水救不了近火
DB + Redis + LocalCache = 高效存储,高效访问
访问速度和花费的关系如下图所示:
使用springboot2.x操作Caffeine Cache
搭建工程:Springboot2.x + MyBatis + MySQL + Caffeine Cache
Caffeine是使用Java8对Guava缓存的重写版本,在Spring 5.0或者Spring Boot 2.0中将取代,基于LRU算法实现,
支持多种缓存过期策略。
-- 新建表 create database if not exists guavach charset utf8; -- 使用表 use guavach; -- 创建用户表tbl_user create table tbl_user( id int(10) not null primary key auto_increment, name varchar(50) not null, age int(20) not null )engine=innodb default charset=utf8; -- 初始化数据 insert into tbl_user values('1','codesheep.cn','25'); insert into tbl_user values('2','hansongwang99','30'); insert into tbl_user values('3','刘能','35'); insert into tbl_user values('4','赵四','38');
<dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency>
引入 CaffeineCache的配置文件 CaffeineCacheConfig
CaffeineCacheConfig
@Configuration @EnableCaching public class CaffeineCacheConfig { @Bean public CacheManager cacheManager(){ CaffeineCacheManager cacheManager = new CaffeineCacheManager(); //Caffeine配置 Caffeine<Object, Object> caffeine = Caffeine.newBuilder() //最后一次写入后经过固定时间过期 .expireAfterWrite(10, TimeUnit.SECONDS) //maximumSize=[long]: 缓存的最大条数 .maximumSize(1000); cacheManager.setCaffeine(caffeine); return cacheManager; } }
说明:
Caffeine配置说明:
recordStats:开发统计功能 注意:
expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。
server: port: 9020 # Mysql spring: datasource: url: jdbc:mysql://localhost:3306/guavach?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver username: root password: root # mybatis配置 mybatis: configuration: map-underscore-to-camel-case: true #debug: true
public class User implements Serializable { private static final long serialVersionUID=1L; private Long id; private String name; private Integer age; public static long getSerialVersionUID() { return serialVersionUID; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
@Mapper public interface UserMapper { @Select("select * from tbl_user") List<User> getUsers(); @Insert("insert into tbl_user values(#{name},#{age})") int addUser(User user); @Select("select * from tbl_user where name=#{userName}") List<User> getUserByName(String userName); }
@Service public class UserService{ @Autowired private UserMapper userMapper; public List<User> getUsers() { return userMapper.getUsers(); } public int addUser(User user) { return userMapper.addUser(user); } @Cacheable(value = "user",key = "#userName") public List<User> getUserByName(String userName) { List<User> users=userMapper.getUserByName(userName); System.out.println("从数据库中读取,而非从缓存读取!"); return users; } }
说明:在 getUsersByName接口上添加了注解:@Cacheable。这是 缓存的使用注解之一,除此之外常用的还有 @CachePut和 @CacheEvit,分别简单介绍一下:
getUsersByName
@Cacheable
@CachePut
@CacheEvit
@CacheEvict
@RestController public class UserController { @Autowired private UserService userService; @Autowired CacheManager cacheManager; @PostMapping("/getuserbyname") public List<User> getUserByName(@RequestBody User user){ System.out.println("------------"); System.out.println("call /getuserbyname"); List<User> users = userService.getUserByName(user.getName()); return users; } @GetMapping("/hehe") public String hehe(){ return "hehhehhehe"; } }
@SpringBootApplication @EnableCaching//新增注解 public class Caffeinecache01Application { public static void main(String[] args) { SpringApplication.run(Caffeinecache01Application.class, args); } }
启动主类,使用postman测试
打开postman,输入json字段,点击send按钮后,显示返回结果
查看IDEA控制台输出
第一次获取时,为从数据库读取
接着点击,间隔时间少于10秒,显示如下结果,可以看到缓存的启用和失效时的效果如下所示(上文 Guava Cache的配置文件中设置了缓存 user的实效时间为 10s):
原文链接:https://www.cnblogs.com/zifanbg/p/13278406.html