Java Code Examples for org.springframework.util.ReflectionUtils#doWithMethods()
The following examples show how to use
org.springframework.util.ReflectionUtils#doWithMethods() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SpringBeanModelConverter.java From citrus-admin with Apache License 2.0 | 6 votes |
@Override public SpringBean convert(String id, T model) { SpringBean converted = super.convert(model); ReflectionUtils.doWithMethods(model.getClass(), method -> { try { Object object = ReflectionUtils.invokeMethod(method, model); if (object != null) { Property property = new Property(); property.setName(getMethodCall(method.getName())); property.setValue(TypeConversionUtils.convertIfNecessary(object, String.class)); converted.getProperties().add(property); } } catch (Exception e) { log.warn(String.format("Unable to access Spring bean property '%s': %s", method.getName(), e.getMessage())); } }, method -> (method.getName().startsWith("get") || method.getName().startsWith("is")) && !method.getName().equals("getClass") && method.getParameterCount() == 0); converted.setClazz(model.getClass().getName()); converted.setId(id); return converted; }
Example 2
Source File: AbstractEndpointConverter.java From citrus-admin with Apache License 2.0 | 6 votes |
/** * Finds setter method on class for given field name. * @param modelClass * @param fieldName * @return */ private Method findSetter(Class<S> modelClass, String fieldName) { final Method[] setter = {null}; ReflectionUtils.doWithMethods(modelClass, method -> { if (method.getName().equals("set" + StringUtils.capitalize(fieldName))) { setter[0] = method; } }, method -> method.getName().startsWith("set")); if (setter[0] == null) { throw new ApplicationRuntimeException(String.format("Unable to find proper setter for field '%s' on model class '%s'", fieldName, modelClass)); } return setter[0]; }
Example 3
Source File: TracerAnnotationClassPointcut.java From sofa-tracer with Apache License 2.0 | 6 votes |
boolean hasAnnotatedMethods(Class<?> clazz) { final AtomicBoolean found = new AtomicBoolean(false); ReflectionUtils.MethodCallback mc = new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException { if (found.get()) { return; } Annotation annotation = AnnotationUtils.findAnnotation(method, AnnotationMethodsResolver.this.annotationType); if (annotation != null) { found.set(true); } } }; ReflectionUtils.doWithMethods(clazz, mc); return found.get(); }
Example 4
Source File: ConsumerProcessor.java From onetwo with Apache License 2.0 | 6 votes |
public static List<Method> findConsumersMethods(Class<?> targetClass, Class<? extends Annotation> consumerAnnotation){ List<Method> consumerMethods = Lists.newArrayList(); ReflectionUtils.doWithMethods(targetClass, m->consumerMethods.add(m), m->{ if(AnnotationUtils.findAnnotation(m, consumerAnnotation)!=null){ Parameter[] parameters = m.getParameters(); if(parameters.length==0 || parameters.length>2){ throw new BaseException("the maximum parameter of consumer method[" + m.toGenericString() + "] is two."); } if(parameters[0].getType()!=ConsumContext.class){ throw new BaseException("the first parameter type of the consumer method[" + m.toGenericString() + "] must be: "+ConsumContext.class); } return true; } return false; }); return consumerMethods; }
Example 5
Source File: FunctionTypeUtils.java From spring-cloud-function with Apache License 2.0 | 5 votes |
/** * Will attempt to discover functional methods on the class. It's applicable for POJOs as well as * functional classes in `java.util.function` package. For the later the names of the methods are * well known (`apply`, `accept` and `get`). For the former it will attempt to discover a single method * following semantics described in (see {@link FunctionalInterface}) * * @param pojoFunctionClass the class to introspect * @return functional method */ public static Method discoverFunctionalMethod(Class<?> pojoFunctionClass) { if (Supplier.class.isAssignableFrom(pojoFunctionClass)) { return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic() && m.getName().equals("get")).findFirst().get(); } else if (Consumer.class.isAssignableFrom(pojoFunctionClass) || BiConsumer.class.isAssignableFrom(pojoFunctionClass)) { return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic() && m.getName().equals("accept")).findFirst().get(); } else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.isAssignableFrom(pojoFunctionClass)) { return Stream.of(ReflectionUtils.getDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic() && m.getName().equals("apply")).findFirst().get(); } List<Method> methods = new ArrayList<>(); ReflectionUtils.doWithMethods(pojoFunctionClass, method -> { if (method.getDeclaringClass() == pojoFunctionClass) { methods.add(method); } }, method -> !method.getDeclaringClass().isAssignableFrom(Object.class) && !method.isSynthetic() && !method.isBridge() && !method.isVarArgs()); Assert.isTrue(methods.size() == 1, "Discovered " + methods.size() + " methods that would qualify as 'functional' - " + methods + ".\n Class '" + pojoFunctionClass + "' is not a FunctionalInterface."); return methods.get(0); }
Example 6
Source File: NacosUtils.java From nacos-spring-project with Apache License 2.0 | 5 votes |
/** * Is {@link NacosProperties @NacosProperties} with default attribute values. * * @param nacosProperties {@link NacosProperties @NacosProperties} * @return If default values , return <code>true</code>,or <code>false</code> */ public static boolean isDefault(final NacosProperties nacosProperties) { final List<Object> records = new LinkedList<Object>(); ReflectionUtils.doWithMethods(nacosProperties.annotationType(), new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { if (Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0) { Object defaultValue = method.getDefaultValue(); if (defaultValue != null) { try { Object returnValue = method.invoke(nacosProperties); if (!defaultValue.equals(returnValue)) { records.add(returnValue); } } catch (Exception e) { } } } } }); return records.isEmpty(); }
Example 7
Source File: NacosValueAnnotationBeanPostProcessor.java From nacos-spring-project with Apache License 2.0 | 5 votes |
private void doWithMethods(final Object bean, final String beanName) { ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException { NacosValue annotation = getAnnotation(method, NacosValue.class); doWithAnnotation(beanName, bean, annotation, method.getModifiers(), method, null); } }); }
Example 8
Source File: AopUtils.java From hsweb-framework with Apache License 2.0 | 5 votes |
public static <T extends Annotation> T findMethodAnnotation(Class targetClass, Method method, Class<T> annClass) { Method m = method; T a = AnnotationUtils.findAnnotation(m, annClass); if (a != null) { return a; } m = ClassUtils.getMostSpecificMethod(m, targetClass); a = AnnotationUtils.findAnnotation(m, annClass); if (a == null) { List<Class> supers = new ArrayList<>(); supers.addAll(Arrays.asList(targetClass.getInterfaces())); if (targetClass.getSuperclass() != Object.class) { supers.add(targetClass.getSuperclass()); } for (Class aClass : supers) { if(aClass==null){ continue; } Method ims[] = new Method[1]; ReflectionUtils.doWithMethods(aClass, im -> { if (im.getName().equals(method.getName()) && im.getParameterCount() == method.getParameterCount()) { ims[0] = im; } }); if (ims[0] != null) { a = findMethodAnnotation(aClass, ims[0], annClass); if (a != null) { return a; } } } } return a; }
Example 9
Source File: FieldAndGetterReflectionEntityInformation.java From spring-data-dynamodb with Apache License 2.0 | 5 votes |
/** * Creates a new {@link FieldAndGetterReflectionEntityInformation} inspecting the * given domain class for a getter carrying the given annotation. * * @param domainClass * must not be {@literal null}. * @param annotation * must not be {@literal null}. */ public FieldAndGetterReflectionEntityInformation(Class<T> domainClass, final Class<? extends Annotation> annotation) { super(domainClass); Assert.notNull(annotation); ReflectionUtils.doWithMethods(domainClass, new MethodCallback() { public void doWith(Method method) { if (method.getAnnotation(annotation) != null) { FieldAndGetterReflectionEntityInformation.this.method = method; return; } } }); if (method == null) { ReflectionUtils.doWithFields(domainClass, new FieldCallback() { public void doWith(Field field) { if (field.getAnnotation(annotation) != null) { FieldAndGetterReflectionEntityInformation.this.field = field; return; } } }); } Assert.isTrue(this.method != null || this.field != null, String.format("No field or method annotated with %s found!", annotation.toString())); Assert.isTrue(this.method == null || this.field == null, String.format("Both field and method annotated with %s found!", annotation.toString())); if (method != null) { ReflectionUtils.makeAccessible(method); } }
Example 10
Source File: MethodIntrospector.java From java-technology-stack with MIT License | 5 votes |
/** * Select methods on the given target type based on the lookup of associated metadata. * <p>Callers define methods of interest through the {@link MetadataLookup} parameter, * allowing to collect the associated metadata into the result map. * @param targetType the target type to search methods on * @param metadataLookup a {@link MetadataLookup} callback to inspect methods of interest, * returning non-null metadata to be associated with a given method if there is a match, * or {@code null} for no match * @return the selected methods associated with their metadata (in the order of retrieval), * or an empty map in case of no match */ public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) { final Map<Method, T> methodMap = new LinkedHashMap<>(); Set<Class<?>> handlerTypes = new LinkedHashSet<>(); Class<?> specificHandlerType = null; if (!Proxy.isProxyClass(targetType)) { specificHandlerType = ClassUtils.getUserClass(targetType); handlerTypes.add(specificHandlerType); } handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType)); for (Class<?> currentHandlerType : handlerTypes) { final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType); ReflectionUtils.doWithMethods(currentHandlerType, method -> { Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); T result = metadataLookup.inspect(specificMethod); if (result != null) { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) { methodMap.put(specificMethod, result); } } }, ReflectionUtils.USER_DECLARED_METHODS); } return methodMap; }
Example 11
Source File: ReflectiveAspectJAdvisorFactory.java From spring4-understanding with Apache License 2.0 | 5 votes |
private List<Method> getAdvisorMethods(Class<?> aspectClass) { final List<Method> methods = new LinkedList<Method>(); ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException { // Exclude pointcuts if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } } }); Collections.sort(methods, METHOD_COMPARATOR); return methods; }
Example 12
Source File: AbstractAutowireCapableBeanFactory.java From spring-analysis-note with MIT License | 5 votes |
/** * Introspect the factory method signatures on the given bean class, * trying to find a common {@code FactoryBean} object type declared there. * @param beanClass the bean class to find the factory method on * @param factoryMethodName the name of the factory method * @return the common {@code FactoryBean} object type, or {@code null} if none */ @Nullable private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) { /** * Holder used to keep a reference to a {@code Class} value. */ class Holder { @Nullable Class<?> value = null; } final Holder objectType = new Holder(); // CGLIB subclass methods hide generic parameters; look at the original user class. Class<?> fbClass = ClassUtils.getUserClass(beanClass); // Find the given factory method, taking into account that in the case of // @Bean methods, there may be parameters present. ReflectionUtils.doWithMethods(fbClass, method -> { if (method.getName().equals(factoryMethodName) && FactoryBean.class.isAssignableFrom(method.getReturnType())) { Class<?> currentType = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class); if (currentType != null) { objectType.value = ClassUtils.determineCommonAncestor(currentType, objectType.value); } } }, ReflectionUtils.USER_DECLARED_METHODS); return (objectType.value != null && Object.class != objectType.value ? objectType.value : null); }
Example 13
Source File: HandlerMethodResolver.java From lams with GNU General Public License v2.0 | 5 votes |
/** * Initialize a new HandlerMethodResolver for the specified handler type. * @param handlerType the handler class to introspect */ public void init(final Class<?> handlerType) { 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 (isHandlerMethod(specificMethod) && (bridgedMethod == specificMethod || !isHandlerMethod(bridgedMethod))) { handlerMethods.add(specificMethod); } else if (isInitBinderMethod(specificMethod) && (bridgedMethod == specificMethod || !isInitBinderMethod(bridgedMethod))) { initBinderMethods.add(specificMethod); } else if (isModelAttributeMethod(specificMethod) && (bridgedMethod == specificMethod || !isModelAttributeMethod(bridgedMethod))) { modelAttributeMethods.add(specificMethod); } } }, ReflectionUtils.USER_DECLARED_METHODS); } this.typeLevelMapping = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); SessionAttributes sessionAttributes = AnnotationUtils.findAnnotation(handlerType, SessionAttributes.class); this.sessionAttributesFound = (sessionAttributes != null); if (this.sessionAttributesFound) { this.sessionAttributeNames.addAll(Arrays.asList(sessionAttributes.names())); this.sessionAttributeTypes.addAll(Arrays.asList(sessionAttributes.types())); } }
Example 14
Source File: AutowiredAnnotationBeanPostProcessor.java From spring4-understanding with Apache License 2.0 | 4 votes |
@Override public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeansException { if (!this.lookupMethodsChecked.contains(beanName)) { ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Lookup lookup = method.getAnnotation(Lookup.class); if (lookup != null) { LookupOverride override = new LookupOverride(method, lookup.value()); try { RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition"); } } } }); this.lookupMethodsChecked.add(beanName); } // Quick check on the concurrent map first, with minimal locking. Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { synchronized (this.candidateConstructorsCache) { candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { Constructor<?>[] rawCandidates = beanClass.getDeclaredConstructors(); List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length); Constructor<?> requiredConstructor = null; Constructor<?> defaultConstructor = null; for (Constructor<?> candidate : rawCandidates) { AnnotationAttributes ann = findAutowiredAnnotation(candidate); if (ann != null) { if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } if (candidate.getParameterTypes().length == 0) { throw new IllegalStateException( "Autowired annotation requires at least one argument: " + candidate); } boolean required = determineRequiredStatus(ann); if (required) { if (!candidates.isEmpty()) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate); } requiredConstructor = candidate; } candidates.add(candidate); } else if (candidate.getParameterTypes().length == 0) { defaultConstructor = candidate; } } if (!candidates.isEmpty()) { // Add default constructor to list of optional constructors, as fallback. if (requiredConstructor == null) { if (defaultConstructor != null) { candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isWarnEnabled()) { logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor " + "is effectively required since there is no default constructor to fall back to: " + candidates.get(0)); } } candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]); } else { candidateConstructors = new Constructor<?>[0]; } this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } } return (candidateConstructors.length > 0 ? candidateConstructors : null); }
Example 15
Source File: InjectAnnotationBeanPostProcessor.java From spring-boot-starter-dubbo with Apache License 2.0 | 4 votes |
private List<InjectionMetadata.InjectedElement> findMethodReferenceMetadata(final Class<?> beanClass) { final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>(); ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } Inject inject = findReferenceAnnotation(bridgedMethod); if (inject == null) { return; } if(!method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))){ return; } if (Modifier.isStatic(method.getModifiers())) { logger.warn("@Reference 静态方法不支持注释: {}" , method); return; } if (method.getParameterTypes().length == 0) { logger.warn("@Reference 注释应该只使用有参数的方法: {}" , method); return; } if(method.getParameterTypes().length>1){ logger.warn("@Reference 注释应该只使用有一个参数的方法: {}" , method); throw new IllegalArgumentException("@Reference 注释应该只使用有一个参数的方法"); } Class<?> requiredType = method.getParameterTypes()[0]; Object bean= getBean(inject, requiredType); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass); if(bean!=null){ elements.add(injectBeanPostProcessor.createAutowiredMethodElement(bridgedMethod, true, pd)); return; } elements.add(new ReferenceMethodElement(method, pd, inject.value())); } }); return elements; }
Example 16
Source File: CompensableAnnotationProcessor.java From txle with Apache License 2.0 | 4 votes |
private void checkMethod(Object bean) { ReflectionUtils.doWithMethods( bean.getClass(), new CompensableMethodCheckingCallback(bean, compensationContext)); }
Example 17
Source File: CompensableAnnotationProcessor.java From servicecomb-pack with Apache License 2.0 | 4 votes |
private void checkMethod(Object bean) { ReflectionUtils.doWithMethods( bean.getClass(), new CompensableMethodCheckingCallback(bean, compensationContext)); }
Example 18
Source File: ReConfigurableBeanAdapter.java From haven-platform with Apache License 2.0 | 4 votes |
private void load() { ReflectionUtils.doWithMethods(this.type, (m) -> { if(!m.isAnnotationPresent(ReConfigObject.class)) { return; } int pc = m.getParameterCount(); final boolean returnVoid = Void.TYPE.equals(m.getReturnType()); // note that in future we may pass ConfigReadContext into this methods, then we must to update below conditions boolean getter = pc == 0 && !returnVoid; boolean setter = pc == 1 && returnVoid; if(!getter && !setter) { return; } if(getter) { Assert.isNull(this.supplier, "Can not override existed getter with: " + m); makeAccessible(m); this.supplier = new GetterSupplier(m); } else { Assert.isNull(this.consumer, "Can not override existed consumer with: " + m); makeAccessible(m); this.consumer = new SetterConsumer(m); } }); if(this.supplier != null && this.consumer != null) { return; } ReflectionUtils.doWithFields(this.type, (f) -> { if(!f.isAnnotationPresent(ReConfigObject.class)) { return; } if(Modifier.isStatic(f.getModifiers())) { throw new IllegalStateException("Static field '" + f + "' must not be annotated with " + ReConfigObject.class ); } if(this.supplier == null) { makeAccessible(f); this.supplier = new FieldSupplier(f); } if(this.consumer == null && !Modifier.isFinal(f.getModifiers())) { makeAccessible(f); this.consumer = new FieldConsumer(f); } }); if(this.supplier == null || this.consumer == null) { throw new RuntimeException("Can not extract setter (" + this.consumer + ") and/or getter (" + this.supplier + ") from annotated bean: " + name); } }
Example 19
Source File: SpringJavaConfigService.java From citrus-admin with Apache License 2.0 | 4 votes |
/** * Finds bean definition element by id and type in Spring application context and * performs unmarshalling in order to return JaxB object. * @param project * @param id * @param type * @return */ public <T> T getBeanDefinition(Class<?> configFile, Project project, String id, Class<T> type) { List<Class<?>> configFiles = new ArrayList<>(); configFiles.add(configFile); configFiles.addAll(getConfigImports(configFile, project)); final Method[] beanDefinitionMethod = new Method[1]; for (Class<?> config : configFiles) { ReflectionUtils.doWithMethods(config, method -> { if (method.getName().equals(id)) { beanDefinitionMethod[0] = method; } else { Bean beanAnnotation = method.getAnnotation(Bean.class); if (beanAnnotation.value().length > 0 && beanAnnotation.value()[0].equals(id)) { beanDefinitionMethod[0] = method; } if (beanAnnotation.name().length > 0 && beanAnnotation.name()[0].equals(id)) { beanDefinitionMethod[0] = method; } } }, method -> method.getAnnotation(Bean.class) != null); if (beanDefinitionMethod[0] != null) { try { Object bean = beanDefinitionMethod[0].invoke(config.newInstance()); if (bean.getClass().equals(type)) { return (T) bean; } else if (type.equals(SpringBean.class)) { SpringBeanModelConverter<Object> springBeanModelConverter = new SpringBeanModelConverter(bean.getClass()); return (T) springBeanModelConverter.convert(id, bean); } else { for (ModelConverter converter : modelConverter) { if (converter.getSourceModelClass().equals(bean.getClass()) && converter.getTargetModelClass().equals(type)) { return (T) converter.convert(id, bean); } } } } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { throw new ApplicationRuntimeException("Failed to access bean definition method in Java config", e); } } } return null; }
Example 20
Source File: AnnotationMethodHandlerExceptionResolver.java From lams with GNU General Public License v2.0 | 4 votes |
/** * Finds the handler method that matches the thrown exception best. * @param handler the handler object * @param thrownException the exception to be handled * @return the best matching method; or {@code null} if none is found */ private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) { final Class<?> handlerType = ClassUtils.getUserClass(handler); final Class<? extends Throwable> thrownExceptionType = thrownException.getClass(); Method handlerMethod = null; Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType); if (handlers != null) { handlerMethod = handlers.get(thrownExceptionType); if (handlerMethod != null) { return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod); } } else { handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16); this.exceptionHandlerCache.put(handlerType, handlers); } final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>(); ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) { method = ClassUtils.getMostSpecificMethod(method, handlerType); List<Class<? extends Throwable>> handledExceptions = getHandledExceptions(method); for (Class<? extends Throwable> handledException : handledExceptions) { if (handledException.isAssignableFrom(thrownExceptionType)) { if (!matchedHandlers.containsKey(handledException)) { matchedHandlers.put(handledException, method); } else { Method oldMappedMethod = matchedHandlers.get(handledException); if (!oldMappedMethod.equals(method)) { throw new IllegalStateException( "Ambiguous exception handler mapped for " + handledException + "]: {" + oldMappedMethod + ", " + method + "}."); } } } } } }); handlerMethod = getBestMatchingMethod(matchedHandlers, thrownException); handlers.put(thrownExceptionType, (handlerMethod == null ? NO_METHOD_FOUND : handlerMethod)); return handlerMethod; }