Add new features on @ControllerAdvice

Prior to this commit, @ControllerAdvice annotated beans would
assist all known Controllers, by applying @ExceptionHandler,
@InitBinder, and @ModelAttribute.

This commit updates the @ControllerAdvice annotation,
which accepts now base package names, assignableTypes,
annotations and basePackageClasses.

If attributes are set, only Controllers that match those
selectors will be assisted by the annotated class.
This commit does not change the default behavior when
no value is set, i.e. @ControllerAdvice().

Issue: SPR-10222
This commit is contained in:
Brian Clozel
2013-10-11 19:28:28 +02:00
committed by Rossen Stoyanchev
parent be4e5d2841
commit c4a8bf9c4d
7 changed files with 450 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 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.
@@ -351,8 +351,8 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
* @return a method to handle the exception, or {@code null}
*/
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
Class<?> handlerType = (handlerMethod != null) ? handlerMethod.getBeanType() : null;
if (handlerMethod != null) {
Class<?> handlerType = handlerMethod.getBeanType();
ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);
if (resolver == null) {
resolver = new ExceptionHandlerMethodResolver(handlerType);
@@ -364,9 +364,11 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
}
}
for (Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
Method method = entry.getValue().resolveMethod(exception);
if (method != null) {
return new ServletInvocableHandlerMethod(entry.getKey().resolveBean(), method);
if(entry.getKey().isApplicableToBeanType(handlerType)) {
Method method = entry.getValue().resolveMethod(exception);
if (method != null) {
return new ServletInvocableHandlerMethod(entry.getKey().resolveBean(), method);
}
}
}
return null;

View File

@@ -776,9 +776,11 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
List<InvocableHandlerMethod> attrMethods = new ArrayList<InvocableHandlerMethod>();
// Global methods first
for (Entry<ControllerAdviceBean, Set<Method>> entry : this.modelAttributeAdviceCache.entrySet()) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
if(entry.getKey().isApplicableToBeanType(handlerType)) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
}
}
for (Method method : methods) {
@@ -806,9 +808,11 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
List<InvocableHandlerMethod> initBinderMethods = new ArrayList<InvocableHandlerMethod>();
// Global methods first
for (Entry<ControllerAdviceBean, Set<Method>> entry : this.initBinderAdviceCache .entrySet()) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
initBinderMethods.add(createInitBinderMethod(bean, method));
if(entry.getKey().isApplicableToBeanType(handlerType)) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
initBinderMethods.add(createInitBinderMethod(bean, method));
}
}
}
for (Method method : methods) {