一個通過 PointcutAdvisor 進(jìn)行方法緩存的注解實現(xiàn)

注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ThreadLocalCache {
}

PointcutAdvisor

@Component
@Order(0)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
public class ThreadLocalCacheSupport implements PointcutAdvisor {

    private static final Object NULL = new Object();

    private ThreadLocal<Map<Object, Object>> threadLocal = new ThreadLocal<>();

    @Getter
    public Pointcut pointcut = new StaticMethodMatcherPointcut() {

        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            return method.getAnnotation(ThreadLocalCache.class) != null;
        }
    };

    public boolean isExistInCache(Object thisObj, Method method, Object[] args) {
        Object key = getCacheKey(thisObj, method, args);

        Map<Object, Object> map = threadLocal.get();
        if (map == null) {
            return false;
        } else {
            return map.containsKey(key);
        }
    }

    public Object getCacheKey(Object thisObj, Method method, Object[] args) {
        return SimpleKeyGenerator.generateKey(thisObj, method, args);
    }

    @Getter
    public MethodInterceptor advice = new MethodInterceptor() {


        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            Object key = getCacheKey(invocation.getThis(), invocation.getMethod(), invocation.getArguments());

            Map<Object, Object> map = threadLocal.get();
            if(map == null) {
                map = new HashMap<>();
                threadLocal.set(map);
            }
            Object o = map.get(key);
            if(o == NULL) {
                return null;
            } else if(o != null) {
                return o;
            }

            Object result = invocation.proceed();
            if(result == null) {
                map.put(key, NULL);
            } else {
                map.put(key, result);
            }
            return result;
        }
    };

    @Override
    public boolean isPerInstance() {
        return true;
    }

    public void removeAll() {
        threadLocal.remove();
    }


    //移除所有的ThreadLocal
    public static void destroy() {
        try {
            ApplicationContextUtil.getBean(ThreadLocalCacheSupport.class).removeAll();
        }catch ( Exception e){
            log.error("ThreadLocalSupport.destroy exception e = [{}]", e);
        }

    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容