概述
Guava、Ehcache、Caffeine都是基于JVM堆内存的本地缓存方案, 从功能和性能角度的对比这里不再多做赘述。在实际生产环境中, 为了避免缓存雪崩, 一般会采用多级缓存策略。
Caffeine基本使用
pom.xml
1 2 3 4 5 <dependency > <groupId > com.github.ben-manes.caffeine</groupId > <artifactId > caffeine</artifactId > <version > 2.9.0</version > </dependency >
缓存配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Configuration public class CacheConfig { @Bean public Cache<String, Object> caffeineCache () { return Caffeine.newBuilder() .expireAfterWrite(60 , TimeUnit.MINUTES) .initialCapacity(100 ) .maximumSize(1000 ) .build(); } }
应用
1 2 3 4 5 6 7 8 9 10 11 12 @Data @ToString public class User { private Long id; private String name; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface UserService { void addUser (User user) ; User getUser (Long id) ; User updateUser (User user) ; void deleteUser (Long id) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 @Slf4j @Service public class UserServiceImpl implements UserService { @Resource private Cache<String, Object> cache; private final Map<Long, User> db = new HashMap<>(); @Override public void addUser (User user) { db.put(user.getId(), user); log.info("saved to db, user={}" , user); } @Override public User getUser (Long id) { User user = (User) cache.getIfPresent(String.valueOf(id)); if (Objects.nonNull(user)) { log.info("get from cache, user={}" , user); return user; } user = db.get(id); log.info("get from db, user={}" , user); if (Objects.nonNull(user)) { log.info("saved to cache, user={}" , user); cache.put(String.valueOf(id), user); } return user; } @Override public User updateUser (User user) { if (!db.containsKey(user.getId())) { return null ; } User oldUser = db.get(user.getId()); oldUser.setName(user.getName()); db.put(user.getId(), oldUser); cache.invalidate(String.valueOf(user.getId())); log.info("invalidate cache, user={}" , user); return oldUser; } @Override public void deleteUser (Long id) { db.remove(id); cache.invalidate(String.valueOf(id)); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @RestController public class UserController { @Resource private UserService userService; @PostMapping("/user") public Object createUser (@RequestBody User user) { userService.addUser(user); return user; } @GetMapping("/user/{id}") public Object getUser (@PathVariable Long id) { return userService.getUser(id); } @PutMapping("/user") public Object updateUser (@RequestBody User user) { return userService.updateUser(user); } @DeleteMapping("/user/{id}") public Object deleteUser (@PathVariable Long id) { userService.deleteUser(id); return id; } }
配合spring-cahce使用
pom.xml
1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-cache</artifactId > <version > 2.4.2</version > </dependency >
修改配置文件
将缓存交给spring接管
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package com.example.caffeine;import com.github.benmanes.caffeine.cache.Cache;import com.github.benmanes.caffeine.cache.Caffeine;import org.springframework.cache.CacheManager;import org.springframework.cache.caffeine.CaffeineCacheManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration public class CacheConfig { @Bean public Cache<String, Object> caffeineCache () { return Caffeine.newBuilder() .expireAfterWrite(60 , TimeUnit.MINUTES) .initialCapacity(100 ) .maximumSize(1000 ) .build(); } @Bean("caffeineCacheManage") public CacheManager caffeineCacheManage () { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(60 , TimeUnit.MINUTES) .initialCapacity(100 ) .maximumSize(1000 )); return cacheManager; } }
重写实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 @Slf4j @Service("caffeineCacheService") @CacheConfig(cacheNames = "caffeineCacheManage") public class UserServiceImpl implements UserService { private final Map<Long, User> db = new HashMap<>(); @Override @CachePut(key = "#user.id") public void addUser (User user) { db.put(user.getId(), user); log.info("saved to db, user={}" , user); } @Override @Cacheable(key = "#id") public User getUser (Long id) { return db.get(id); } @Override @CacheEvict(key = "#user.id") public User updateUser (User user) { if (!db.containsKey(user.getId())) { return null ; } User oldUser = db.get(user.getId()); oldUser.setName(user.getName()); db.put(user.getId(), oldUser); log.info("invalidate cache, user={}" , user); return oldUser; } @Override @CacheEvict(key = "#id") public void deleteUser (Long id) { db.remove(id); } }
测试
1 2 @Resource(name = "caffeineCacheService") private UserService userService;
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。