知道怎样行使Spring Cache后,我们必要进一步思索,就是怎样扩展。那么带着题目出发。
好比Spring Cache不支持批量key的缓存,像上文我们举的例子,我们但愿缓存的key是userId,而不是Collection userIds。以userId为key,这样的缓存掷中率更高,存储的本钱更小。
- @Cacheable(cacheNames = "users")
- public Map<Long, User> getUser(final Collection<Long> userIds) {}
以是我们要实现对Spring Cache举办扩展。step3中我们已经大抵相识了Spring Cache的实现。那么实现这个扩展的成果就是拆分Collection userIds,缓存掷中的从缓存中获取,没有掷中的,挪用源要领。
- @Aspect
- @Component
- public class CacheExtenionAspect {
-
- @Autowired
- private CacheExtensionManage cacheExtensionManage;
-
- /**
- * 返回的功效中缓存掷中的从缓存中获取,没有掷中的挪用原本的要领获取
- * @param joinPoint
- * @return
- */
- @Around("@annotation(org.springframework.cache.annotation.Cacheable)")
- @SuppressWarnings("unchecked")
- public Object aroundCache(final ProceedingJoinPoint joinPoint) {
-
- // 修改掉Collection值,cacheResult必要从头结构一个
- args[0] = cacheResult.getMiss();
- try {
- final Map<Object, Object> notHit = CollectionUtils.isEmpty(cacheResult.getMiss()) ? null
- : (Map<Object, Object>) (method.invoke(target, args));
- final Map<Object, Object> hits = cacheResult.getHit();
- if (Objects.isNull(notHit)) {
- return hits;
- }
- // 配置缓存
- cacheResult.getCache().putAll(notHit);
- hits.putAll(notHit);
- return hits;
- }
- }
- 然后扩展Cache,CacheManage
- 重写Cache的查找缓存要领,返回新的CacheResult
-
- public static Object lookup(final CacheExtension cache, final Object key) {
- if (key instanceof Collection) {
- final Collection<Object> originalKeys = ((Collection) key);
- if (originalKeys == null || originalKeys.isEmpty()) {
- return CacheResult.builder().cache(cache).miss(
- Collections.emptySet())
- .build();
- }
- final List<Object> keys = originalKeys.stream()
- .filter(Objects::nonNull).collect(Collectors.toList());
- final Map<Object, Object> hits = cache.getAll(keys);
- final Set<Object> miss = new HashSet(keys);
- miss.removeAll(hits.keySet());
- return CacheResult.builder().cache(cache).hit(hits).miss(miss).build();
- }
- return null;
- }
- CacheResult就是新的缓存功效名目
-
- @Builder
- @Setter
- @Getter
- static class CacheResult {
- final CacheExtension cache;
- // 掷中的缓存功效
- final Map<Object, Object> hit;
- // 必要从头挪用源要领的keys
- private Set<Object> miss;
- }
然后扩展CacheManager,没什么重写,就是自界说一种manager范例 (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|