protected boolean shouldRegister(Class<?> klass) {
   Method[] methods = ReflectionUtils.getAllDeclaredMethods(klass);
   for (Method method : methods) {
     if (method.getAnnotation(Subscribe.class) != null) {
       return true;
     }
   }
   return false;
 }
 private boolean canReturnExpectedType(
     AnnotatedMethodFilter filter, Class<?> targetType, TypeConverter typeConverter) {
   if (expectedType == null) {
     return true;
   }
   List<Method> methods =
       filter.filter(Arrays.asList(ReflectionUtils.getAllDeclaredMethods(targetType)));
   for (Method method : methods) {
     if (typeConverter.canConvert(
         TypeDescriptor.valueOf(method.getReturnType()), TypeDescriptor.valueOf(expectedType))) {
       return true;
     }
   }
   return false;
 }
 /**
  * Retrieve all candidate methods for the given class, considering the {@link
  * RootBeanDefinition#isNonPublicAccessAllowed()} flag. Called as the starting point for factory
  * method determination.
  */
 private Method[] getCandidateMethods(final Class<?> factoryClass, final RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
     return AccessController.doPrivileged(
         new PrivilegedAction<Method[]>() {
           @Override
           public Method[] run() {
             return (mbd.isNonPublicAccessAllowed()
                 ? ReflectionUtils.getAllDeclaredMethods(factoryClass)
                 : factoryClass.getMethods());
           }
         });
   } else {
     return (mbd.isNonPublicAccessAllowed()
         ? ReflectionUtils.getAllDeclaredMethods(factoryClass)
         : factoryClass.getMethods());
   }
 }
  /**
   * Augments a {@link UriComponentsBuilder} with queries based on the methods annotated with {@link
   * FilterParameter}
   *
   * @param builder the builder to augment
   * @param instance the instance to inspect and invoke
   */
  @SuppressWarnings("unchecked")
  public static void augment(UriComponentsBuilder builder, Object instance) {
    Method[] methods = ReflectionUtils.getAllDeclaredMethods(instance.getClass());
    Arrays.sort(methods, MethodNameComparator.INSTANCE);

    for (Method method : methods) {
      FilterParameter filterParameter =
          AnnotationUtils.getAnnotation(method, FilterParameter.class);
      if (filterParameter == null) {
        continue;
      }

      String value = getValue(method, instance);
      if (StringUtils.hasText(value)) {
        builder.queryParam(filterParameter.value(), value);
      }
    }
  }
  protected Serializable getIdValue(final Object domainObject) {
    final Class<?> clazz = domainObject.getClass();
    // 直接用getId
    try {
      final AclManaged aclManaged = AnnotationUtils.findAnnotation(clazz, AclManaged.class);
      final Method getIdMethod = clazz.getMethod(aclManaged.getIdMethodName());
      if (getIdMethod != null) {
        final Object id = ReflectionUtils.invokeMethod(getIdMethod, domainObject);
        if (id == null) {
          logger.warn("此对象id为空:" + domainObject);
          return null;
        }
        if (!(id instanceof Serializable)) {
          logger.warn("此对象id不能序列化:" + domainObject + " ,id:" + id); // 来到这里就扯淡了吧?
          return null;
        }
        return (Serializable) id;
      }
    } catch (final NoSuchMethodException e) {
      // 没有getId方法就不用它呗
    } catch (final SecurityException e) {
      logger.debug(domainObject.getClass().getName() + "getId方法访问不能访问。", e);
    }
    // 没有getId方法

    // 用标注了@Id注解的字段
    final Field[] fields = clazz.getDeclaredFields();

    Serializable idValueStr = concatIdValues(domainObject, fields);
    if (idValueStr == null) {
      idValueStr = concatIdValues(domainObject, ReflectionUtils.getAllDeclaredMethods(clazz));
    }
    if (idValueStr == null) {
      logger.warn(domainObject.getClass().getName() + "没有id字段。");
      return null;
    }
    if (String.valueOf(idValueStr).isEmpty()) {
      logger.warn("此对象的id字段值都是空字符串:" + domainObject);
      return null;
    }
    return idValueStr;
  }
  /**
   * Find a matching method with the specified name for the specified arguments.
   *
   * @return a matching method, or <code>null</code> if none
   * @return
   */
  protected Method findMatchingMethod() {
    String targetMethod = getTargetMethod();
    Object[] arguments = getArguments();
    int argCount = arguments.length;

    Method[] candidates = ReflectionUtils.getAllDeclaredMethods(getTargetClass());
    int minTypeDiffWeight = Integer.MAX_VALUE;
    Method matchingMethod = null;

    for (Method candidate : candidates) {
      if (candidate.getName().equals(targetMethod)) {
        Class[] paramTypes = candidate.getParameterTypes();
        if (paramTypes.length == argCount) {
          int typeDiffWeight = getTypeDifferenceWeight(paramTypes, arguments);
          if (typeDiffWeight < minTypeDiffWeight) {
            minTypeDiffWeight = typeDiffWeight;
            matchingMethod = candidate;
          }
        }
      }
    }

    return matchingMethod;
  }