本地缓存使用GuavaCache

最近在项目中需要使用一个产品组件,通过一个产品接口做模糊查询,通过产品id得到产品信息,可是对于产品的编辑和展示用到的地方特别多,即项目中会频繁的调用一个接口。这个问题走了一些弯路,比如在表中增加展示字段,数据返回前调员工接口做转换,或者列表展示时由前端并发处理,最后证明这些办法都不是很好。最后想到了本地缓存。

在系统中,一些访问量大但是数据量小、与业务无关的缓存适合采用本地缓存。为什么不采用分布式缓存呢?分布式集群缓存的构建、维护成本较高,不太适合做紧急的项目。而本地缓存访问速度快,使用方便,劣势是数据更新的一致性难以保证,使用范围有所限制,但是这种场景下的使用足够了。

在GuavaCache中缓存的容器被定义为接口Cache的实现类,这些实现类都是线程安全的,因此通常定义为一个单例。

LoadingCache graphs = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .removalListener(MY_LISTENER)
        .build(
            new CacheLoader() {
                public Graph load(Key key) throws AnyException {
                    return createExpensiveGraph(key);
                }
        });
以上是官方给的demo

通常来说,Guava Cache适用于:
你愿意消耗一些内存空间来提升速度。
你预料到某些键会被查询一次以上。
缓存中存放的数据总量不会超出内存容量。(Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试Memcached这类工具)
如果你的场景符合上述的每一条,Guava Cache就适合你。

回收策略
常用定时回收:

expireAfterAccess(long, TimeUnit):缓存项在给定时间内没有被读/写访问,则回收。请注意这种缓存的回收顺序和基于大小回收一样。expireAfterWrite(long, TimeUnit):缓存项在给定时间内没有被写访问(创建或覆盖),则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。
与spring结合使用

@Service
public class GuavaCache {
    public LoadingCache userCache;
    @Autowired
    private UserDao userDao;
 
    @PostConstruct
    public void init() {
         userCache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .build(
                        new CacheLoader() {
                            public User load(String key) throws Exception {
                                return userDao.findUserByMobile(key);
                            }
                        });
    }

你可能感兴趣的:(JavaWeb,Develop)