public void invoke(MethodInvocation invocation) throws Throwable {
      next.invoke(invocation);
      if (invocation.found() || invocation.getParameterTypes().length != 1) {
        return;
      }

      if (!invocation.isIsOrGet()) {
        return;
      }

      MethodInvocation getterInvocation =
          new MethodInvocation(
              invocation.getName(),
              invocation.getReturnType(),
              invocation.getGenericReturnType(),
              EMPTY_CLASS_ARRAY,
              invocation.getDelegate(),
              EMPTY);
      next.invoke(getterInvocation);
      if (getterInvocation.found() && getterInvocation.getResult() != null) {
        invocation.setResult(getterInvocation.getResult());
      } else {
        invocation.setResult(invocation.getParameters()[0]);
      }
    }
 public Method get(MethodInvocation invocation) {
   Class<?> owner = invocation.getDelegate().getClass();
   String name = invocation.getName();
   Class<?>[] parameterTypes = invocation.getParameterTypes();
   MethodInvocationKey key = new MethodInvocationKey(owner, name, parameterTypes);
   lock.readLock().lock();
   Optional<Method> cached = store.get(key);
   if (cached == null) {
     cacheMiss++;
     lock.readLock().unlock();
     lock.writeLock().lock();
     try {
       cached = store.get(key);
       if (cached == null) {
         cached = lookup(owner, name, parameterTypes);
         if (cacheMiss % 10 == 0) {
           removeDirtyEntries();
         }
         store.put(key, cached);
       }
       lock.readLock().lock();
     } finally {
       lock.writeLock().unlock();
     }
   } else {
     cacheHit++;
   }
   try {
     return cached.orNull();
   } finally {
     lock.readLock().unlock();
   }
 }
    public void invoke(MethodInvocation invocation) throws Throwable {
      Method targetMethod = locateMethod(invocation);
      if (targetMethod == null) {
        return;
      }

      Object returnValue;
      try {
        returnValue = targetMethod.invoke(invocation.getDelegate(), invocation.getParameters());
      } catch (InvocationTargetException e) {
        throw e.getCause();
      }

      invocation.setResult(returnValue);
    }
    public void invoke(MethodInvocation invocation) throws Throwable {
      Matcher matcher = IS_SUPPORT_METHOD.matcher(invocation.getName());
      if (!matcher.matches()) {
        next.invoke(invocation);
        return;
      }

      String getterName = String.format("get%s", matcher.group(1));
      MethodInvocation getterInvocation =
          new MethodInvocation(
              getterName,
              invocation.getReturnType(),
              invocation.getGenericReturnType(),
              new Class[0],
              invocation.getDelegate(),
              EMPTY);
      next.invoke(getterInvocation);
      invocation.setResult(getterInvocation.found());
    }