public void afterReturning(MethodInvocation methodInvocation, Object result) throws Throwable {

    MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(methodInvocation);

    ThreadLocalCachable threadLocalCachable = findAnnotation(methodTargetClassKey);

    if (threadLocalCachable == _nullThreadLocalCacheable) {
      return;
    }

    ThreadLocalCache<Object> threadLocalCache =
        ThreadLocalCacheManager.getThreadLocalCache(
            threadLocalCachable.scope(), methodTargetClassKey.toString());

    String cacheKey = _buildCacheKey(methodInvocation.getArguments());

    if (result == null) {
      threadLocalCache.put(cacheKey, nullResult);
    } else {
      threadLocalCache.put(cacheKey, result);
    }
  }
  public Object before(MethodInvocation methodInvocation) throws Throwable {
    MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(methodInvocation);

    ThreadLocalCachable threadLocalCachable = findAnnotation(methodTargetClassKey);

    if (threadLocalCachable == _nullThreadLocalCacheable) {
      return null;
    }

    ThreadLocalCache<?> threadLocalCache =
        ThreadLocalCacheManager.getThreadLocalCache(
            threadLocalCachable.scope(), methodTargetClassKey.toString());

    String cacheKey = _buildCacheKey(methodInvocation.getArguments());

    Object value = threadLocalCache.get(cacheKey);

    if (value == nullResult) {
      return null;
    }

    return value;
  }