您好,我是湘王,这是我的慕课手记,欢迎您来,欢迎您再来~
说了很多Caffeine的基本特性,但是骡子是马,终归还是要看能不能拉磨。SpringBoot有两种使用Caffeine的方式:
1、直接引入Caffeine依赖,然后使用Caffeine方法实现缓存;
2、引入Caffeine和Spring Cache依赖,使用注解方式实现缓存。
先实现第一种方式(之前已实现过,整合到SpringBoot),这种方式比较灵活。再使用第二种方式(用注解实现Caffeine缓存功能),这种方式比较方便。
先引入依赖:
<dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency>
在配置文件中加入(这是可选的):
## CAFFEINE customer.caffeine.initialCapacity=50 customer.caffeine.maximumSize=500 customer.caffeine.expireAfterWrite=86400
声明注入代码:
/** * 声明注入代码 * * @author 湘王 */ @Configuration @Component public class WebConfiguration extends WebMvcConfigurationSupport { /** * 进程外缓存初始化 * */ @Bean("cache") public LoadingCache<String, String> cache() { return Caffeine.newBuilder() .initialCapacity(1024) .maximumSize(1024) .expireAfterWrite(1, TimeUnit.HOURS) .build(key -> { return ""; }); } }
然后在代码中调用:
/** * 功能描述 * * @author 湘王 */ public class CaffeineTest { @Resource private LoadingCache<String, String> cache; /** * 保存缓存数据 * */ public void setCache(final String key, final String value) { cache.put(key, value); } /** * 读取缓存数据 * */ public String getCache(final String key) { return cache.get(key); } /** * 清除缓存数据 * */ public void clearCache(final String key) { cache.invalidate(key); } }
然后再来看看第二种方式。先引入依赖:
<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>
在属性文件中加入配置:
## CAFFEINE spring.cache.cache-names=test spring.cache.type=caffeine spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=300s
定义一个实体类(之前用过的类):
/** * 用户entity * * @author 湘王 */ public class SysUser implements Serializable, RowMapper<SysUser> { private static final long serialVersionUID = -1214743110268373599L; private int id; private int bid; private String username; private String password; private int scope; // 0:全部,1:部门及以下,2:仅个人 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") protected Date createtime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") protected Date updatetime; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @JsonIgnore public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getScope() { return scope; } public void setScope(int scope) { this.scope = scope; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public Date getUpdatetime() { return updatetime; } public void setUpdatetime(Date updatetime) { this.updatetime = updatetime; } @Override public SysUser mapRow(ResultSet result, int i) throws SQLException { SysUser user = new SysUser(); user.setId(result.getInt("id")); user.setUsername(result.getString("username")); user.setPassword(result.getString("password")); user.setCreatetime(result.getTimestamp("createtime")); user.setUpdatetime(result.getTimestamp("updatetime")); return user; } }
然后定义服务类:
/** * 缓存服务 * * @author 湘王 */ @Service public class CaffeineService { /** * 将新增的用户信息放入缓存 * */ @CachePut(value = "test", key = "#id") public int addUser(int id, String username, String password) { String sql = ""; // TODO SOMETHING return -1; } /** * 从缓存读取用户信息,id作为key * */ @Cacheable(value = "test", key = "#id") public SysUser queryById(int id) { System.out.println("从数据库读取:" + id); String sql = ""; // TODO SOMETHING return new SysUser(); } /** * 从缓存读取用户信息,username作为key * */ @Cacheable(value = "test", key = "#username") public SysUser queryByUsername(String username) { System.out.println("从数据库读取:" + username); String sql = ""; // TODO SOMETHING return new SysUser(); } }
再定义Contorller类:
/** * 缓存COntroller * * @author 湘王 */ @RestController public class CacheController { @Resource private CaffeineService caffeineService; /** * 添加用户 * */ @PostMapping("/user/add") public String add(int id, String username, String password) { caffeineService.addUser(id, username, password); return "添加用户成功"; } /** * 查询用户 * */ @GetMapping("/user/id") public String id(int id) { SysUser user = caffeineService.queryById(id); return "查询到用户:" + user.getUsername(); } /** * 查询用户 * */ @GetMapping("/user/username") public String username(String username) { SysUser user = caffeineService.queryByUsername(username); return "查询到用户:" + user.getUsername(); } }
先添加用户,再分别通过ID和用户名查询,可以看到:
1、第一次查询,会从数据库中读取;
2、第二次查询,就直接从Caffeine中读取了。
当超过设定的300s后,再次读取又会从数据中查询。
使用注解的方式简单、快速,但注解缺点是不能灵活操控,如异步存储和无法查看统计信息。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~