code: public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
      A annotation = getAnnotation(method, annotationType);
      Class<?> clazz = method.getDeclaringClass();
      if (annotation == null) {
        annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
      }
      while (annotation == null) {
        clazz = clazz.getSuperclass();
        if (clazz == null || clazz.equals(Object.class)) {
          break;
        }
        try {
          Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
          annotation = getAnnotation(equivalentMethod, annotationType);
        }
        catch (NoSuchMethodException ex) {
          // No equivalent method found
        }
        if (annotation == null) {
          annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
        }
      }
      return annotation;
    }
docs: Get a single {@link java.lang.annotation.Annotation} of {@code annotationType} from the supplied {@link java.lang.reflect.Method},
  traversing its super methods if no annotation can be found on the given method itself.
  <p>Annotations on methods are not inherited by default, so we need to handle this explicitly.
  @param method the method to look for annotations on
  @param annotationType the annotation class to look for
  @param <A> annotation type
  @return the annotation found, or {@code null} if none found