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:
committed by
Rossen Stoyanchev
parent
be4e5d2841
commit
c4a8bf9c4d
@@ -0,0 +1,144 @@
|
||||
package org.springframework.web.method;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class ControllerAdviceBeanTests {
|
||||
|
||||
@Test
|
||||
public void shouldMatchAll() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new SimpleControllerAdvice());
|
||||
assertApplicable("should match all", bean, AnnotatedController.class);
|
||||
assertApplicable("should match all", bean, ImplementationController.class);
|
||||
assertApplicable("should match all", bean, InheritanceController.class);
|
||||
assertApplicable("should match all", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basePackageSupport() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new BasePackageSupport());
|
||||
assertApplicable("base package support", bean, AnnotatedController.class);
|
||||
assertApplicable("base package support", bean, ImplementationController.class);
|
||||
assertApplicable("base package support", bean, InheritanceController.class);
|
||||
assertNotApplicable("bean not in package", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basePackageValueSupport() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new BasePackageValueSupport());
|
||||
assertApplicable("base package support", bean, AnnotatedController.class);
|
||||
assertApplicable("base package support", bean, ImplementationController.class);
|
||||
assertApplicable("base package support", bean, InheritanceController.class);
|
||||
assertNotApplicable("bean not in package", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotationSupport() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new AnnotationSupport());
|
||||
assertApplicable("annotation support", bean, AnnotatedController.class);
|
||||
assertNotApplicable("this bean is not annotated", bean, InheritanceController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void markerClassSupport() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new MarkerClassSupport());
|
||||
assertApplicable("base package class support", bean, AnnotatedController.class);
|
||||
assertApplicable("base package class support", bean, ImplementationController.class);
|
||||
assertApplicable("base package class support", bean, InheritanceController.class);
|
||||
assertNotApplicable("bean not in package", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotMatch() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new ShouldNotMatch());
|
||||
assertNotApplicable("should not match", bean, AnnotatedController.class);
|
||||
assertNotApplicable("should not match", bean, ImplementationController.class);
|
||||
assertNotApplicable("should not match", bean, InheritanceController.class);
|
||||
assertNotApplicable("should not match", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assignableTypesSupport() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new AssignableTypesSupport());
|
||||
assertApplicable("controller implements assignable", bean, ImplementationController.class);
|
||||
assertApplicable("controller inherits assignable", bean, InheritanceController.class);
|
||||
assertNotApplicable("not assignable", bean, AnnotatedController.class);
|
||||
assertNotApplicable("not assignable", bean, String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleMatch() {
|
||||
ControllerAdviceBean bean = new ControllerAdviceBean(new MultipleSelectorsSupport());
|
||||
assertApplicable("controller implements assignable", bean, ImplementationController.class);
|
||||
assertApplicable("controller is annotated", bean, AnnotatedController.class);
|
||||
assertNotApplicable("should not match", bean, InheritanceController.class);
|
||||
}
|
||||
|
||||
private void assertApplicable(String message, ControllerAdviceBean controllerAdvice,
|
||||
Class<?> controllerBeanType) {
|
||||
assertNotNull(controllerAdvice);
|
||||
assertTrue(message,controllerAdvice.isApplicableToBeanType(controllerBeanType));
|
||||
}
|
||||
|
||||
private void assertNotApplicable(String message, ControllerAdviceBean controllerAdvice,
|
||||
Class<?> controllerBeanType) {
|
||||
assertNotNull(controllerAdvice);
|
||||
assertFalse(message,controllerAdvice.isApplicableToBeanType(controllerBeanType));
|
||||
}
|
||||
|
||||
// ControllerAdvice classes
|
||||
|
||||
@ControllerAdvice
|
||||
static class SimpleControllerAdvice {}
|
||||
|
||||
@ControllerAdvice(annotations = ControllerAnnotation.class)
|
||||
static class AnnotationSupport {}
|
||||
|
||||
@ControllerAdvice(basePackageClasses = MarkerClass.class)
|
||||
static class MarkerClassSupport {}
|
||||
|
||||
@ControllerAdvice(assignableTypes = {ControllerInterface.class,
|
||||
AbstractController.class})
|
||||
static class AssignableTypesSupport {}
|
||||
|
||||
@ControllerAdvice(basePackages = "org.springframework.web.method")
|
||||
static class BasePackageSupport {}
|
||||
|
||||
@ControllerAdvice("org.springframework.web.method")
|
||||
static class BasePackageValueSupport {}
|
||||
|
||||
@ControllerAdvice(annotations = ControllerAnnotation.class,
|
||||
assignableTypes = ControllerInterface.class)
|
||||
static class MultipleSelectorsSupport {}
|
||||
|
||||
@ControllerAdvice(basePackages = "java.util",
|
||||
annotations = RestController.class)
|
||||
static class ShouldNotMatch {}
|
||||
|
||||
// Support classes
|
||||
|
||||
static class MarkerClass {}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface ControllerAnnotation {}
|
||||
|
||||
@ControllerAnnotation
|
||||
public static class AnnotatedController {}
|
||||
|
||||
static interface ControllerInterface {}
|
||||
|
||||
static class ImplementationController implements ControllerInterface {}
|
||||
|
||||
static abstract class AbstractController {}
|
||||
|
||||
static class InheritanceController extends AbstractController {}
|
||||
}
|
||||
Reference in New Issue
Block a user