| 知道如何使用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类型 (编辑:南平站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |