@Override protected AbstractExceptionHandlerMethodResolver createExceptionHandlerMethodResolverFor(Class<?> beanType) { return new AnnotationExceptionHandlerMethodResolver(beanType); }
private static Map<Class<? extends Throwable>, Method> initExceptionMappings(Class<?> handlerType) { Map<Method, MessageExceptionHandler> methods = MethodIntrospector.selectMethods(handlerType, (MethodIntrospector.MetadataLookup<MessageExceptionHandler>) method -> AnnotatedElementUtils.findMergedAnnotation(method, MessageExceptionHandler.class)); Map<Class<? extends Throwable>, Method> result = new HashMap<>(); for (Map.Entry<Method, MessageExceptionHandler> entry : methods.entrySet()) { Method method = entry.getKey(); List<Class<? extends Throwable>> exceptionTypes = new ArrayList<>(); exceptionTypes.addAll(Arrays.asList(entry.getValue().value())); if (exceptionTypes.isEmpty()) { exceptionTypes.addAll(getExceptionsFromMethodSignature(method)); } for (Class<? extends Throwable> exceptionType : exceptionTypes) { Method oldMethod = result.put(exceptionType, method); if (oldMethod != null && !oldMethod.equals(method)) { throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" + exceptionType + "]: {" + oldMethod + ", " + method + "}"); } } } return result; }
private void initMessagingAdviceCache(@Nullable List<MessagingAdviceBean> beans) { if (beans == null) { return; } for (MessagingAdviceBean bean : beans) { Class<?> type = bean.getBeanType(); if (type != null) { AnnotationExceptionHandlerMethodResolver resolver = new AnnotationExceptionHandlerMethodResolver(type); if (resolver.hasExceptionMappings()) { registerExceptionHandlerAdvice(bean, resolver); if (logger.isTraceEnabled()) { logger.trace("Detected @MessageExceptionHandler methods in " + bean); } } } } }
/** * A constructor that finds {@link MessageExceptionHandler} methods in the given type. * @param handlerType the type to introspect */ public AnnotationExceptionHandlerMethodResolver(Class<?> handlerType) { super(initExceptionMappings(handlerType)); }
@Test public void resolveMethodAgainstCause() { IllegalStateException exception = new IllegalStateException(new IOException()); assertEquals("handleIOException", this.resolver.resolveMethod(exception).getName()); }
/** * A constructor that finds {@link MessageExceptionHandler} methods in the given type. * @param handlerType the type to introspect */ public AnnotationExceptionHandlerMethodResolver(Class<?> handlerType) { super(initExceptionMappings(handlerType)); }
@Test public void resolveMethodNoMatch() { Exception exception = new Exception(); assertNull("1st lookup", this.resolver.resolveMethod(exception)); assertNull("2nd lookup from cache", this.resolver.resolveMethod(exception)); }
@Test(expected = IllegalStateException.class) public void ambiguousExceptionMapping() { new AnnotationExceptionHandlerMethodResolver(AmbiguousController.class); }
private void initMessagingAdviceCache(@Nullable List<MessagingAdviceBean> beans) { if (beans == null) { return; } for (MessagingAdviceBean bean : beans) { Class<?> type = bean.getBeanType(); if (type != null) { AnnotationExceptionHandlerMethodResolver resolver = new AnnotationExceptionHandlerMethodResolver(type); if (resolver.hasExceptionMappings()) { registerExceptionHandlerAdvice(bean, resolver); if (logger.isInfoEnabled()) { logger.info("Detected @MessageExceptionHandler methods in " + bean); } } } } }
/** * A constructor that finds {@link MessageExceptionHandler} methods in the given type. * @param handlerType the type to introspect */ public AnnotationExceptionHandlerMethodResolver(Class<?> handlerType) { super(initExceptionMappings(handlerType)); }
private static Map<Class<? extends Throwable>, Method> initExceptionMappings(Class<?> handlerType) { Map<Method, MessageExceptionHandler> methods = MethodIntrospector.selectMethods(handlerType, (MethodIntrospector.MetadataLookup<MessageExceptionHandler>) method -> AnnotatedElementUtils.findMergedAnnotation(method, MessageExceptionHandler.class)); Map<Class<? extends Throwable>, Method> result = new HashMap<>(); for (Map.Entry<Method, MessageExceptionHandler> entry : methods.entrySet()) { Method method = entry.getKey(); List<Class<? extends Throwable>> exceptionTypes = new ArrayList<>(); exceptionTypes.addAll(Arrays.asList(entry.getValue().value())); if (exceptionTypes.isEmpty()) { exceptionTypes.addAll(getExceptionsFromMethodSignature(method)); } for (Class<? extends Throwable> exceptionType : exceptionTypes) { Method oldMethod = result.put(exceptionType, method); if (oldMethod != null && !oldMethod.equals(method)) { throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" + exceptionType + "]: {" + oldMethod + ", " + method + "}"); } } } return result; }
@Test public void resolveMethodFromArgumentWithErrorType() { AssertionError exception = new AssertionError(); assertEquals("handleAssertionError", this.resolver.resolveMethod(new IllegalStateException(exception)).getName()); }
@Test(expected = IllegalStateException.class) public void noExceptionMapping() { new AnnotationExceptionHandlerMethodResolver(NoExceptionController.class); }
private void initMessagingAdviceCache(@Nullable List<MessagingAdviceBean> beans) { if (beans == null) { return; } for (MessagingAdviceBean bean : beans) { Class<?> type = bean.getBeanType(); if (type != null) { AnnotationExceptionHandlerMethodResolver resolver = new AnnotationExceptionHandlerMethodResolver(type); if (resolver.hasExceptionMappings()) { registerExceptionHandlerAdvice(bean, resolver); if (logger.isTraceEnabled()) { logger.trace("Detected @MessageExceptionHandler methods in " + bean); } } } } }
/** * A constructor that finds {@link MessageExceptionHandler} methods in the given type. * @param handlerType the type to introspect */ public AnnotationExceptionHandlerMethodResolver(Class<?> handlerType) { super(initExceptionMappings(handlerType)); }
private static Map<Class<? extends Throwable>, Method> initExceptionMappings(Class<?> handlerType) { Map<Method, MessageExceptionHandler> methods = MethodIntrospector.selectMethods(handlerType, (MethodIntrospector.MetadataLookup<MessageExceptionHandler>) method -> AnnotatedElementUtils.findMergedAnnotation(method, MessageExceptionHandler.class)); Map<Class<? extends Throwable>, Method> result = new HashMap<>(); for (Map.Entry<Method, MessageExceptionHandler> entry : methods.entrySet()) { Method method = entry.getKey(); List<Class<? extends Throwable>> exceptionTypes = new ArrayList<>(); exceptionTypes.addAll(Arrays.asList(entry.getValue().value())); if (exceptionTypes.isEmpty()) { exceptionTypes.addAll(getExceptionsFromMethodSignature(method)); } for (Class<? extends Throwable> exceptionType : exceptionTypes) { Method oldMethod = result.put(exceptionType, method); if (oldMethod != null && !oldMethod.equals(method)) { throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" + exceptionType + "]: {" + oldMethod + ", " + method + "}"); } } } return result; }
@Test public void resolveMethodFromAnnotation() { IOException exception = new IOException(); assertEquals("handleIOException", this.resolver.resolveMethod(exception).getName()); }
@Override protected AbstractExceptionHandlerMethodResolver createExceptionHandlerMethodResolverFor(Class<?> beanType) { return new AnnotationExceptionHandlerMethodResolver(beanType); }
private static Map<Class<? extends Throwable>, Method> initExceptionMappings(Class<?> handlerType) { Map<Method, MessageExceptionHandler> methods = MethodIntrospector.selectMethods(handlerType, (MethodIntrospector.MetadataLookup<MessageExceptionHandler>) method -> AnnotatedElementUtils.findMergedAnnotation(method, MessageExceptionHandler.class)); Map<Class<? extends Throwable>, Method> result = new HashMap<>(); for (Map.Entry<Method, MessageExceptionHandler> entry : methods.entrySet()) { Method method = entry.getKey(); List<Class<? extends Throwable>> exceptionTypes = new ArrayList<>(); exceptionTypes.addAll(Arrays.asList(entry.getValue().value())); if (exceptionTypes.isEmpty()) { exceptionTypes.addAll(getExceptionsFromMethodSignature(method)); } for (Class<? extends Throwable> exceptionType : exceptionTypes) { Method oldMethod = result.put(exceptionType, method); if (oldMethod != null && !oldMethod.equals(method)) { throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" + exceptionType + "]: {" + oldMethod + ", " + method + "}"); } } } return result; }
@Test public void resolveMethodFromArgument() { IllegalArgumentException exception = new IllegalArgumentException(); assertEquals("handleIllegalArgumentException", this.resolver.resolveMethod(exception).getName()); }