美文网首页
一个通过 PointcutAdvisor 进行方法缓存的注解实现

一个通过 PointcutAdvisor 进行方法缓存的注解实现

作者: JennTu | 来源:发表于2019-08-20 17:45 被阅读0次

注解

@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);
        }

    }
}

相关文章

网友评论

      本文标题:一个通过 PointcutAdvisor 进行方法缓存的注解实现

      本文链接:https://www.haomeiwen.com/subject/tsfmsctx.html