diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java index 7423c9cca3..0dec918c2b 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -64,15 +64,17 @@ public @interface ControllerAdvice { * {@code @ControllerAdvice("org.my.pkg")} is equivalent to * {@code @ControllerAdvice(basePackages="org.my.pkg")}. * @since 4.0 + * @see #basePackages() */ String[] value() default {}; /** * Array of base packages. - * Controllers that belong to those base packages will be included, e.g.: - * {@code @ControllerAdvice(basePackages="org.my.pkg")} or - * {@code @ControllerAdvice(basePackages={"org.my.pkg","org.my.other.pkg"})} - *

{@link #value()} is an alias for this attribute. + * Controllers that belong to those base packages or sub-packages thereof + * will be included, e.g.: {@code @ControllerAdvice(basePackages="org.my.pkg")} + * or {@code @ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"})}. + *

{@link #value()} is an alias for this attribute, simply allowing for + * more concise use of the annotation. *

Also consider using {@link #basePackageClasses()} as a type-safe * alternative to String-based package names. * @since 4.0 diff --git a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java index b9d4cb0e24..5ac8556c32 100644 --- a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java +++ b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java @@ -114,7 +114,7 @@ public class ControllerAdviceBean implements Ordered { /** * Returns the order value extracted from the {@link ControllerAdvice} - * annotation or {@link Ordered#LOWEST_PRECEDENCE} otherwise. + * annotation, or {@link Ordered#LOWEST_PRECEDENCE} otherwise. */ @Override public int getOrder() { @@ -122,8 +122,9 @@ public class ControllerAdviceBean implements Ordered { } /** - * Returns the type of the contained bean. - * If the bean type is a CGLIB-generated class, the original, user-defined class is returned. + * Return the type of the contained bean. + *

If the bean type is a CGLIB-generated class, the original + * user-defined class is returned. */ public Class getBeanType() { Class clazz = (this.bean instanceof String ? @@ -139,7 +140,7 @@ public class ControllerAdviceBean implements Ordered { } /** - * Checks whether the given bean type should be assisted by this + * Check whether the given bean type should be assisted by this * {@code @ControllerAdvice} instance. * @param beanType the type of the bean to check * @see org.springframework.web.bind.annotation.ControllerAdvice @@ -151,7 +152,7 @@ public class ControllerAdviceBean implements Ordered { } else if (beanType != null) { for (String basePackage : this.basePackages) { - if (ClassUtils.getPackageName(beanType).startsWith(basePackage)) { + if (beanType.getName().startsWith(basePackage)) { return true; } } @@ -224,18 +225,22 @@ public class ControllerAdviceBean implements Ordered { Set basePackages = new LinkedHashSet(); for (String basePackage : annotation.value()) { if (StringUtils.hasText(basePackage)) { - basePackages.add(basePackage); + basePackages.add(adaptBasePackage(basePackage)); } } for (String basePackage : annotation.basePackages()) { if (StringUtils.hasText(basePackage)) { - basePackages.add(basePackage); + basePackages.add(adaptBasePackage(basePackage)); } } for (Class markerClass : annotation.basePackageClasses()) { - basePackages.add(ClassUtils.getPackageName(markerClass)); + basePackages.add(adaptBasePackage(ClassUtils.getPackageName(markerClass))); } return basePackages; } + private static String adaptBasePackage(String basePackage) { + return (basePackage.endsWith(".") ? basePackage : basePackage + "."); + } + } diff --git a/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java b/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java index 1088df8eb4..2b14c9e00b 100644 --- a/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/ControllerAdviceBeanTests.java @@ -102,12 +102,12 @@ public class ControllerAdviceBeanTests { private void assertApplicable(String message, ControllerAdviceBean controllerAdvice, Class controllerBeanType) { assertNotNull(controllerAdvice); - assertTrue(message,controllerAdvice.isApplicableToBeanType(controllerBeanType)); + assertTrue(message, controllerAdvice.isApplicableToBeanType(controllerBeanType)); } private void assertNotApplicable(String message, ControllerAdviceBean controllerAdvice, Class controllerBeanType) { assertNotNull(controllerAdvice); - assertFalse(message,controllerAdvice.isApplicableToBeanType(controllerBeanType)); + assertFalse(message, controllerAdvice.isApplicableToBeanType(controllerBeanType)); } @@ -138,6 +138,7 @@ public class ControllerAdviceBeanTests { @ControllerAdvice(basePackages = "java.util", annotations = {RestController.class}) static class ShouldNotMatch {} + // Support classes static class MarkerClass {}