Consistent ControllerAdvice applicability against user-declared class
Issue: SPR-16496
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -27,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -440,13 +442,18 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||
* Spring-managed beans were detected.
|
||||
* @param handlerMethod the method where the exception was raised (may be {@code null})
|
||||
* @param exception the raised exception
|
||||
* @return a method to handle the exception, or {@code null}
|
||||
* @return a method to handle the exception, or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(@Nullable HandlerMethod handlerMethod, Exception exception) {
|
||||
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
|
||||
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
|
||||
@Nullable HandlerMethod handlerMethod, Exception exception) {
|
||||
|
||||
Class<?> handlerType = null;
|
||||
|
||||
if (handlerMethod != null) {
|
||||
// Local exception handler methods on the controller class itself.
|
||||
// To be invoked through the proxy, even in case of an interface-based proxy.
|
||||
handlerType = handlerMethod.getBeanType();
|
||||
ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);
|
||||
if (resolver == null) {
|
||||
resolver = new ExceptionHandlerMethodResolver(handlerType);
|
||||
@@ -456,14 +463,20 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||
if (method != null) {
|
||||
return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
|
||||
}
|
||||
// For advice applicability check below (involving base packages, assignable types
|
||||
// and annotation presence), use target class instead of interface-based proxy.
|
||||
if (Proxy.isProxyClass(handlerType)) {
|
||||
handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
|
||||
if (entry.getKey().isApplicableToBeanType(handlerType)) {
|
||||
ControllerAdviceBean advice = entry.getKey();
|
||||
if (advice.isApplicableToBeanType(handlerType)) {
|
||||
ExceptionHandlerMethodResolver resolver = entry.getValue();
|
||||
Method method = resolver.resolveMethod(exception);
|
||||
if (method != null) {
|
||||
return new ServletInvocableHandlerMethod(entry.getKey().resolveBean(), method);
|
||||
return new ServletInvocableHandlerMethod(advice.resolveBean(), method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user