• Guava缓存工具类封装和使用


    本文为博主原创,未经允许不得转载:

      Guava是谷歌提供的一款强大的java工具库,里面包含了很多方便且高效的工具,在项目开发中有业务场景需要保存数据到内存当中,

    且只需要保存固定时间就可以,该数据只在服务调用其他服务的时候会获取。主要有两个场景:1.项目中需要调用第三方服务,第三方服务

    每次调用时,需要获取第三方提供的token,,2.项目中需要校验第三方的一些固定数据。。所以考虑用Guava的缓存类,将上述中的数据

    保存到Guava中,在获取的时候直接使用,如果没有则获取数据,并将其保存到Guava中。

      第一步:定义Guava缓存基类,其中要实现 InitializingBean接口,这个接口为Spring提供的接口,:

    import java.util.concurrent.ExecutionException;
    
    import org.apache.http.client.utils.CloneUtils;
    import org.springframework.beans.factory.InitializingBean;
    
    import com.google.common.cache.CacheBuilder;
    import com.google.common.cache.CacheLoader;
    import com.google.common.cache.LoadingCache;
    
    
    /**
     * 〈一句话功能简述〉<br>
     * guava内存缓存基类
     *
     * @author 16110508
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public abstract class AbstractMemoryCache<PK, T> implements InitializingBean {
    
        private LoadingCache<PK, T> cache;
    
        protected abstract CacheBuilder<Object, Object> getCacheBuilder(CacheBuilder<Object, Object> cacheBuilder);
    
        protected abstract CacheLoader<PK, T> getCacheLoader();
    
        protected LoadingCache<PK, T> getCache() {
            return cache;
        }
    
        public T getValue(PK pk) throws FucdnException {
            try {
                return CloneUtils.cloneObject(this.cache.get(pk));
            } catch (CloneNotSupportedException | ExecutionException e) {
                throw new Exception(e);
            }
        }
    
        public void setValue(PK pk, T t) {
            this.cache.put(pk, t);
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            CacheLoader<PK, T> cacheLoader = this.getCacheLoader();
            CacheBuilder<Object, Object> cacheBuilder = this.getCacheBuilder(CacheBuilder.newBuilder());
            this.cache = cacheBuilder.build(cacheLoader);
        }
    
    }

    InitializingBean接口为spring提供的一个接口,用来加载保存数据,可打开源码看下,通过注释可了解到该接口主要用来初始化加载数据:

    package org.springframework.beans.factory;
    
    /**
     * Interface to be implemented by beans that need to react once all their
     * properties have been set by a BeanFactory: for example, to perform custom
     * initialization, or merely to check that all mandatory properties have been set.
     *
     * <p>An alternative to implementing InitializingBean is specifying a custom
     * init-method, for example in an XML bean definition.
     * For a list of all bean lifecycle methods, see the BeanFactory javadocs.
     *
     * @author Rod Johnson
     * @see BeanNameAware
     * @see BeanFactoryAware
     * @see BeanFactory
     * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
     * @see org.springframework.context.ApplicationContextAware
     */
    public interface InitializingBean {
    
        /**
         * Invoked by a BeanFactory after it has set all bean properties supplied
         * (and satisfied BeanFactoryAware and ApplicationContextAware).
         * <p>This method allows the bean instance to perform initialization only
         * possible when all bean properties have been set and to throw an
         * exception in the event of misconfiguration.
         * @throws Exception in the event of misconfiguration (such
         * as failure to set an essential property) or if initialization fails.
         */
        void afterPropertiesSet() throws Exception;
    
    }

      第2步:实现基类,封装业务数据保存和调用

    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    
    import com.google.common.cache.CacheBuilder;
    import com.google.common.cache.CacheLoader;
    
    
    import org.springframework.stereotype.Component;
    
    /**
     * 〈一句话功能简述〉<br>
     * 〈缓存〉
     *
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     * @date 20190807
     */
    @Component("tokenCache")
    public class TokenCache extends AbstractMemoryCache<String, Map<String, Object>> {
    
        // 过期时间: 3小时
        private static final int EXPIRE_SEC_TIME = 3;
    
        // 最多保存的key的数量
        private static final int MAX_KEY_SIZE = 500;
    ·  

      ·// 设置存储数量和过期时间 @Override
    protected CacheBuilder<Object, Object> getCacheBuilder(CacheBuilder<Object, Object> cacheBuilder) { return cacheBuilder.maximumSize(MAX_KEY_SIZE).expireAfterWrite(EXPIRE_SEC_TIME, TimeUnit.HOURS); } @Override protected CacheLoader<String, Map<String, Object>> getCacheLoader() { return new CacheLoader<String, Map<String, Object>>() { @Override public Map<String, Object> load(String key) throws Exception { return new HashMap<>(); } }; } // 根据key获取token值 public Object genToken(String key) throws Exception { return super.getValue(key).get(key); }
      // 在guava中根据key缓存值
    public void setCache(String key,Object token) { Map<String, Object> tokenMap = new HashMap<>(); tokenMap.put(key, token); super.setValue(key, tokenMap); } }

     第三步调用:由于在第二步类上加了spring的@Component注解,在服务启动时会自动加载到服务中,当做bean正常调用即可。

       

  • 相关阅读:
    hash算法
    TCP/IP四层与OSI七层模型
    di
    VSCode安装程序——java开发
    java中的多线程
    C#ThreadPool类—多线程
    学习-思考
    DataTable通过Select进行过滤
    javascript遍历对象属性
    WebClient 与HttpClient 的区别
  • 原文地址:https://www.cnblogs.com/zjdxr-up/p/12525351.html
Copyright © 2020-2023  润新知