/** * Select handler methods for the given handler type. * <p>Callers define handler methods of interest through the {@link MethodFilter} parameter. * @param handlerType the handler type to search handler methods on * @param handlerMethodFilter a {@link MethodFilter} to help recognize handler methods of interest * @return the selected methods, or an empty set */ public static Set<Method> selectMethods(final Class<?> handlerType, final MethodFilter handlerMethodFilter) { final Set<Method> handlerMethods = new LinkedHashSet<Method>(); Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>(); Class<?> specificHandlerType = null; if (!Proxy.isProxyClass(handlerType)) { handlerTypes.add(handlerType); specificHandlerType = handlerType; } handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces())); for (Class<?> currentHandlerType : handlerTypes) { final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType); ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) { Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); if (handlerMethodFilter.matches(specificMethod) && (bridgedMethod == specificMethod || !handlerMethodFilter.matches(bridgedMethod))) { handlerMethods.add(specificMethod); } } }, ReflectionUtils.USER_DECLARED_METHODS); } return handlerMethods; }
private static Method getMethod(Class<?> controllerType, final String methodName, final Object... args) { MethodFilter selector = new MethodFilter() { @Override public boolean matches(Method method) { String name = method.getName(); int argLength = method.getParameterTypes().length; return (name.equals(methodName) && argLength == args.length); } }; Set<Method> methods = MethodIntrospector.selectMethods(controllerType, selector); if (methods.size() == 1) { return methods.iterator().next(); } else if (methods.size() > 1) { throw new IllegalArgumentException(String.format( "Found two methods named '%s' accepting arguments %s in controller %s: [%s]", methodName, Arrays.asList(args), controllerType.getName(), methods)); } else { throw new IllegalArgumentException("No method named '" + methodName + "' with " + args.length + " arguments found in controller " + controllerType.getName()); } }
/** * Perform the given callback operation on all matching methods of the * given class and superclasses. * <p>The same named method occurring on subclass and superclass will * appear twice, unless excluded by the specified {@link MethodFilter}. * @param targetClass class to start looking at * @param mc the callback to invoke for each method * @param mf the filter that determines the methods to apply the callback to */ public static void doWithMethods(Class targetClass, MethodCallback mc, MethodFilter mf) throws IllegalArgumentException { // Keep backing up the inheritance hierarchy. do { Method[] methods = targetClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if (mf != null && !mf.matches(methods[i])) { continue; } try { mc.doWith(methods[i]); } catch (IllegalAccessException ex) { throw new IllegalStateException( "Shouldn't be illegal to access method '" + methods[i].getName() + "': " + ex); } } targetClass = targetClass.getSuperclass(); } while (targetClass != null); }
/** * Select handler methods for the given handler type. * <p>Callers define handler methods of interest through the {@link MethodFilter} parameter. * @param handlerType the handler type to search handler methods on * @param handlerMethodFilter a {@link MethodFilter} to help recognize handler methods of interest * @return the selected methods, or an empty set */ public static Set<Method> selectMethods(final Class<?> handlerType, final MethodFilter handlerMethodFilter) { final Set<Method> handlerMethods = new LinkedHashSet<Method>(); Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>(); Class<?> specificHandlerType = null; if (!Proxy.isProxyClass(handlerType)) { handlerTypes.add(handlerType); specificHandlerType = handlerType; } handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces())); for (Class<?> currentHandlerType : handlerTypes) { final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType); ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() { public void doWith(Method method) { Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); if (handlerMethodFilter.matches(specificMethod) && (bridgedMethod == specificMethod || !handlerMethodFilter.matches(bridgedMethod))) { handlerMethods.add(specificMethod); } } }, ReflectionUtils.USER_DECLARED_METHODS); } return handlerMethods; }
/** * Select handler methods for the given handler type. * <p>Callers define handler methods of interest through the {@link MethodFilter} parameter. * @param handlerType the handler type to search handler methods on * @param handlerMethodFilter a {@link MethodFilter} to help recognize handler methods of interest * @return the selected methods, or an empty set * @see MethodIntrospector#selectMethods(Class, MethodFilter) */ public static Set<Method> selectMethods(Class<?> handlerType, MethodFilter handlerMethodFilter) { return MethodIntrospector.selectMethods(handlerType, handlerMethodFilter); }