All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pjq.weibo.openapi.support.WeiboCacheHandler Maven / Gradle / Ivy

/*
 * Copyright © 2021 pengjianqiang
 * All rights reserved.
 * 项目名称:微博开放平台API-JAVA SDK
 * 项目描述:基于微博开放平台官网的weibo4j-oauth2-beta3.1.1包及新版接口做二次开发
 * 项目地址:https://github.com/qqxadyy/weibo-openapi-4java
 * 许可证信息:见下文
 *
 * ======================================================================
 *
 * The MIT License
 * Copyright © 2021 pengjianqiang
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package pjq.weibo.openapi.support;

import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Expiry;

import pjq.commons.utils.CheckUtils;
import weibo4j.model.WeiboException;

/**
 * 微博相关缓存处理器父类
* 已有用本地内存实现的默认类,如果需要自行实现缓存的部分,需要继承该父类,并只实现相关方法
* 实现相关方法时,记得先使用{@link #checkKey}或{@link #checkKeyAndValue}检查key、value * * @author pengjianqiang * @date 2021年1月21日 */ public abstract class WeiboCacheHandler { private static WeiboCacheHandler customInstance; private static class InstanceHolder { private static WeiboCacheHandler INSTANCE = (null != customInstance ? customInstance : new DefaultWeiboCacheHandler()); } /** * 返回微博缓存处理器的实例
* 如果有调用{@link WeiboImplRegister#registCacheHandler(WeiboCacheHandler)}方法,则返回其参数对象;否则返回SDK默认的缓存实现 * * @return */ public static WeiboCacheHandler getInstance() { return InstanceHolder.INSTANCE; } protected void checkKey(String key) { if (CheckUtils.isEmpty(key)) { throw WeiboException.ofParamCanNotNull("key"); } } protected void checkKeyAndValue(String key, String value) { if (!CheckUtils.areNotEmpty(key, value)) { throw WeiboException.ofParamCanNotNull("key和value"); } } /** * 根据key缓存value,缓存不过期
* 注意:如果已有缓存值且缓存有过期时间,则更新缓存值时要继续保留过期时间,不能清空该时间 * * @param key * 缓存key * @param value * 缓存值 * @throws WeiboException */ public abstract void cache(String key, String value) throws WeiboException; /** * 根据key缓存value * * @param key * 缓存key * @param value * 缓存值 * @param duration * key的有效时间,为空时表示不过期 * @throws WeiboException */ public void cache(String key, String value, Duration duration) throws WeiboException { if (CheckUtils.isNull(duration)) { duration = Duration.ofSeconds(0L); } cache(key, value, duration.getSeconds()); } /** * 根据key缓存value * * @param key * 缓存key * @param value * 缓存值 * @param expiresInSeconds * key的有效时间,单位秒,为0时表示不过期 * @throws WeiboException */ public abstract void cache(String key, String value, long expiresInSeconds) throws WeiboException; /** * 判断key是否存在 * * @param key * @return * @throws WeiboException */ public abstract boolean exists(String key) throws WeiboException; /** * 从缓存中读取值,key不存在时返回null * * @param key * @return * @throws WeiboException */ public abstract String get(String key) throws WeiboException; /** * 根据key删除缓存 * * @param key * @throws WeiboException */ public abstract void remove(String key) throws WeiboException; /** * 根据key删除缓存,并返回被删除的缓存值 * * @param key * @throws WeiboException */ public abstract String popup(String key) throws WeiboException; private static class DefaultWeiboCacheHandler extends WeiboCacheHandler { private static final Duration NO_EXPIRES = Duration.ofNanos(Long.MAX_VALUE); private static final Map expiresMap = new ConcurrentHashMap<>(); private static Cache cache = Caffeine.newBuilder().initialCapacity(300).maximumSize(1000).expireAfter(new Expiry() { @Override public long expireAfterCreate(@NonNull String key, @NonNull String value, long currentTime) { Duration expireDuration = expiresMap.containsKey(key) ? Duration.ofSeconds(expiresMap.get(key)) : NO_EXPIRES; if (expireDuration.compareTo(Duration.ofSeconds(0L)) <= 0 || expireDuration.compareTo(NO_EXPIRES) > 0) { expireDuration = NO_EXPIRES; } expiresMap.remove(key); return expireDuration.toNanos(); // 注意方法要求返回的是nanoseconds(微毫秒)单位 } @Override public long expireAfterUpdate(@NonNull String key, @NonNull String value, long currentTime, @NonNegative long currentDuration) { return currentDuration; // 更新缓存后的过期时间直接返回currentDuration即可,表示按当前剩下的缓存时间 } @Override public long expireAfterRead(@NonNull String key, @NonNull String value, long currentTime, @NonNegative long currentDuration) { if (key.startsWith(WeiboCacher.KEY_PREFIX_STATE)) { return 0L; // state的缓存读取后马上失效,防止被二次使用 } else { return currentDuration; // 读取缓存后的过期时间直接返回currentDuration即可,表示按当前剩下的缓存时间 } } }).build(); @Override public void cache(String key, String value) throws WeiboException { cache(key, value, 0); } @Override public void cache(String key, String value, long expiresInSeconds) throws WeiboException { // 由于默认使用的Caffeine缓存是在builder中设置有效期策略,需要expiresMap把有效期带进expireXXX方法中 checkKeyAndValue(key, value); expiresMap.put(key, expiresInSeconds); cache.put(key, value); // put实际上Caffeine内部会判断新建还是更新key } @Override public boolean exists(String key) throws WeiboException { checkKey(key); return CheckUtils.isNotEmpty(get(key)); } @Override public String get(String key) throws WeiboException { checkKey(key); return cache.getIfPresent(key); } @Override public void remove(String key) throws WeiboException { checkKey(key); cache.invalidate(key); } @Override public String popup(String key) throws WeiboException { String cacheValue = get(key); remove(key); return cacheValue; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy