diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/ControllerAdviceBean.java b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java similarity index 77% rename from spring-web/src/main/java/org/springframework/web/bind/support/ControllerAdviceBean.java rename to spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java index fd1b204ed4a..d1aa1a36d0e 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/ControllerAdviceBean.java +++ b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.web.bind.support; +package org.springframework.web.method; import java.util.ArrayList; import java.util.List; @@ -29,7 +29,11 @@ import org.springframework.web.bind.annotation.ControllerAdvice; /** * Encapsulates information about an {@linkplain ControllerAdvice @ControllerAdvice} - * bean without requiring the bean to be instantiated. + * Spring-managed bean without necessarily requiring it to be instantiated. + * + *

The {@link #findAnnotatedBeans(ApplicationContext)} method can be used to discover + * such beans. However, an {@code ControllerAdviceBean} may be created from + * any object, including ones without an {@code @ControllerAdvice}. * * @author Rossen Stoyanchev * @since 3.2 @@ -55,7 +59,12 @@ public class ControllerAdviceBean implements Ordered { "Bean factory [" + beanFactory + "] does not contain bean " + "with name [" + beanName + "]"); this.bean = beanName; this.beanFactory = beanFactory; - this.order = initOrder(this.beanFactory.getType(beanName)); + this.order = initOrderFromBeanType(this.beanFactory.getType(beanName)); + } + + private static int initOrderFromBeanType(Class beanType) { + Order annot = AnnotationUtils.findAnnotation(beanType, Order.class); + return (annot != null) ? annot.value() : Ordered.LOWEST_PRECEDENCE; } /** @@ -65,13 +74,12 @@ public class ControllerAdviceBean implements Ordered { public ControllerAdviceBean(Object bean) { Assert.notNull(bean, "'bean' must not be null"); this.bean = bean; - this.order = initOrder(bean.getClass()); + this.order = initOrderFromBean(bean); this.beanFactory = null; } - private static int initOrder(Class beanType) { - Order orderAnnot = AnnotationUtils.findAnnotation(beanType, Order.class); - return (orderAnnot != null) ? orderAnnot.value() : Ordered.LOWEST_PRECEDENCE; + private static int initOrderFromBean(Object bean) { + return (bean instanceof Ordered) ? ((Ordered) bean).getOrder() : initOrderFromBeanType(bean.getClass()); } /** @@ -79,7 +87,7 @@ public class ControllerAdviceBean implements Ordered { * {@linkplain ControllerAdvice @ControllerAdvice} in the given * ApplicationContext and wrap them as {@code ControllerAdviceBean} instances. */ - public static List findBeans(ApplicationContext applicationContext) { + public static List findAnnotatedBeans(ApplicationContext applicationContext) { List beans = new ArrayList(); for (String name : applicationContext.getBeanDefinitionNames()) { if (applicationContext.findAnnotationOnBean(name, ControllerAdvice.class) != null) { @@ -90,12 +98,9 @@ public class ControllerAdviceBean implements Ordered { } /** - * Return a bean instance if necessary resolving the bean name through the BeanFactory. + * Returns the order value extracted from the {@link ControllerAdvice} + * annotation or {@link Ordered#LOWEST_PRECEDENCE} otherwise. */ - public Object resolveBean() { - return (this.bean instanceof String) ? this.beanFactory.getBean((String) this.bean) : this.bean; - } - public int getOrder() { return this.order; } @@ -111,6 +116,13 @@ public class ControllerAdviceBean implements Ordered { return ClassUtils.getUserClass(clazz); } + /** + * Return a bean instance if necessary resolving the bean name through the BeanFactory. + */ + public Object resolveBean() { + return (this.bean instanceof String) ? this.beanFactory.getBean((String) this.bean) : this.bean; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 17d01fcf180..34d2d2aa5f7 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -29,13 +29,15 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** - * Encapsulates information about a bean method consisting of a {@linkplain #getMethod() method} and a - * {@linkplain #getBean() bean}. Provides convenient access to method parameters, the method return value, - * method annotations. + * Encapsulates information about a bean method consisting of a + * {@linkplain #getMethod() method} and a {@linkplain #getBean() bean}. Provides + * convenient access to method parameters, the method return value, method + * annotations. * - *

The class may be created with a bean instance or with a bean name (e.g. lazy bean, prototype bean). - * Use {@link #createWithResolvedBean()} to obtain an {@link HandlerMethod} instance with a bean instance - * initialized through the bean factory. + *

The class may be created with a bean instance or with a bean name (e.g. lazy + * bean, prototype bean). Use {@link #createWithResolvedBean()} to obtain an + * {@link HandlerMethod} instance with a bean instance initialized through the + * bean factory. * * @author Arjen Poutsma * @author Rossen Stoyanchev diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index eca11c04f06..d3a49419081 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -41,8 +41,8 @@ import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.support.ControllerAdviceBean; import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.method.ControllerAdviceBean; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver; import org.springframework.web.method.annotation.MapMethodProcessor; @@ -285,7 +285,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce logger.debug("Looking for exception mappings: " + getApplicationContext()); } - List beans = ControllerAdviceBean.findBeans(getApplicationContext()); + List beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); Collections.sort(beans, new OrderComparator()); for (ControllerAdviceBean bean : beans) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index e41592b3158..31453b87f89 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -54,7 +54,6 @@ import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.support.ControllerAdviceBean; import org.springframework.web.bind.support.DefaultDataBinderFactory; import org.springframework.web.bind.support.DefaultSessionAttributeStore; import org.springframework.web.bind.support.SessionAttributeStore; @@ -67,6 +66,7 @@ import org.springframework.web.context.request.async.AsyncTask; import org.springframework.web.context.request.async.AsyncWebRequest; import org.springframework.web.context.request.async.AsyncWebUtils; import org.springframework.web.context.request.async.WebAsyncManager; +import org.springframework.web.method.ControllerAdviceBean; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethodSelector; import org.springframework.web.method.annotation.ErrorsMethodArgumentResolver; @@ -592,7 +592,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i logger.debug("Looking for controller advice: " + getApplicationContext()); } - List beans = ControllerAdviceBean.findBeans(getApplicationContext()); + List beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); Collections.sort(beans, new OrderComparator()); for (ControllerAdviceBean bean : beans) {